From 22bec236d210687c3bd9431530c56efcab250341 Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Mon, 29 May 2017 18:29:51 +0530 Subject: [PATCH 1/9] gulpfile error handlers for pipes added --- gulpfile.js | 99 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 24 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index fdd99d4f..1583a032 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -221,11 +221,25 @@ var gulp = require('gulp'), gutil = require('gulp-util'); +/*=============================================== += Handler for all the stream errors = +=================================================*/ +/** + * Logs the error occured in the pipe without killing the gulp process + * emits an end event to the corresponding stream + * @function endErrorProcess + * @param {Error} err + */ +function endErrorProcess(err){ + console.log(err); + this.emit('end'); +} + /*================================================ = Report Errors to Console = ================================================*/ -gulp.on('error', function(e) { +gulp.on('error', function(e) { throw(e); }); @@ -244,14 +258,16 @@ gulp.task('clean', function () { path.join(config.dest, 'l10n'), path.join(config.dest, 'app.manifest') ], { read: false }) - .pipe(rimraf()); + .pipe(rimraf()) + .on('error', endErrorProcess); }); gulp.task('clean:manifest', function () { return gulp.src([ path.join(config.dest, 'app.manifest') ], { read: false }) - .pipe(rimraf()); + .pipe(rimraf()) + .on('error', endErrorProcess); }); @@ -279,7 +295,8 @@ gulp.task('connect', function() { gulp.task('livereload', function () { gulp.src(path.join(config.dest, '*.html')) - .pipe(connect.reload()); + .pipe(connect.reload()) + .on('error', endErrorProcess); }); @@ -295,10 +312,12 @@ gulp.task('images', function () { progressive: true, svgoPlugins: [{removeViewBox: false}], use: [pngcrush()] - })); + })) + .on('error', endErrorProcess); } - return stream.pipe(gulp.dest(path.join(config.dest, 'images'))); + return stream.pipe(gulp.dest(path.join(config.dest, 'images'))) + .on('error', endErrorProcess); }); @@ -308,7 +327,8 @@ gulp.task('images', function () { gulp.task('fonts', function() { return gulp.src(config.vendor.fonts) - .pipe(gulp.dest(path.join(config.dest, 'fonts'))); + .pipe(gulp.dest(path.join(config.dest, 'fonts'))) + .on('error', endErrorProcess); }); /*================================== @@ -317,7 +337,8 @@ gulp.task('fonts', function() { gulp.task('l10n', function() { return gulp.src('src/l10n/**/*') - .pipe(gulp.dest(path.join(config.dest, 'l10n'))); + .pipe(gulp.dest(path.join(config.dest, 'l10n'))) + .on('error', endErrorProcess); }); @@ -358,7 +379,9 @@ function buildHtml (env) { return gulp.src(['src/html/**/*.html']) .pipe(replace('', inject.join('\n '))) - .pipe(gulp.dest(config.dest)); + .on('error', endErrorProcess) + .pipe(gulp.dest(config.dest)) + .on('error', endErrorProcess); } gulp.task('html', function() { @@ -377,10 +400,13 @@ gulp.task('html:production', function() { gulp.task('sass', function () { gulp.src('./src/sass/app.sass') .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(sass({ includePaths: [ path.resolve(__dirname, 'src/sass'), path.resolve(__dirname, 'bower_components'), path.resolve(__dirname, 'bower_components/bootstrap-sass/assets/stylesheets') ] - }).on('error', sass.logError)) + }) + .on('error', sass.logError)) .pipe(postcss([ autoprefixer({ browsers: ['last 2 versions', 'Android >= 4'] }) ])) + .on('error', endErrorProcess) /* Currently not working with sourcemaps .pipe(mobilizer('app.css', { 'app.css': { @@ -394,11 +420,15 @@ gulp.task('sass', function () { })) */ .pipe(gulpif(config.cssmin, cssmin())) + .on('error', endErrorProcess) .pipe(rename({suffix: '.min'})) + .on('error', endErrorProcess) .pipe(sourcemaps.write('.', { sourceMappingURLPrefix: '/css/' })) - .pipe(gulp.dest(path.join(config.dest, 'css'))); + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'css'))) + .on('error', endErrorProcess); }); /*==================================================================== @@ -408,7 +438,9 @@ gulp.task('sass', function () { gulp.task('jshint', function() { return gulp.src('./src/js/**/*.js') .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')); + .on('error', endErrorProcess) + .pipe(jshint.reporter('jshint-stylish')) + .on('error', endErrorProcess); }); @@ -422,50 +454,66 @@ gulp.task('js:app', function() { return streamqueue({ objectMode: true }, // Vendor: angular, mobile-angular-ui, etc. gulp.src(config.vendor.js) - .pipe(sourcemaps.init()), + .pipe(sourcemaps.init()) + .on('error', endErrorProcess), // app.js is configured gulp.src('./src/js/app.js') .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(replace('value(\'config\', {}). // inject:app:config', 'value(\'config\', ' + JSON.stringify(config.app) + ').')) + .on('error', endErrorProcess) .pipe(babel({ presets: ['es2015'] - })), + })) + .on('error', endErrorProcess), // rest of app logic gulp.src(['./src/js/**/*.js', '!./src/js/app.js', '!./src/js/widgets.js']) .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(babel({ presets: ['es2015'], plugins: ['transform-object-assign'] })) - .pipe(ngFilesort()), + .on('error', endErrorProcess) + .pipe(ngFilesort()) + .on('error', endErrorProcess), // app templates gulp.src(['src/templates/**/*.html']).pipe(templateCache({ module: 'Teem' })) .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(babel({ presets: ['es2015'] })) + .on('error', endErrorProcess) ) .pipe(concat('app.js')) + .on('error', endErrorProcess) .pipe(ngAnnotate()) + .on('error', endErrorProcess) .pipe(gulpif(config.uglify, uglify())) + .on('error', endErrorProcess) .pipe(rename({suffix: '.min'})) + .on('error', endErrorProcess) .pipe(sourcemaps.write('.', { sourceMappingURLPrefix: '/js/' })) - .pipe(gulp.dest(path.join(config.dest, 'js'))); + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'js'))) + .on('error', endErrorProcess); }); gulp.task('js:widgets', function() { return gulp.src('./src/js/widgets.js') .pipe(uglify()) - .pipe(gulp.dest(path.join(config.dest, 'js'))); + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'js'))) + .on('error', endErrorProcess); }); gulp.task('js', function(callback) { var tasks = ['js:app', 'js:widgets']; - seq(tasks, callback); }); @@ -481,9 +529,8 @@ gulp.task('cordova:sync:clean', function() { return gulp.src([dest], { read: false }) - .pipe(rimraf()); - - + .pipe(rimraf()) + .on('error', endErrorProcess); }); @@ -493,7 +540,8 @@ gulp.task('cordova:sync:copy', function() { return gulp.src([ source + '{cordova.js,cordova_plugins.js,plugins/**/*}']) - .pipe(gulp.dest(dest)); + .pipe(gulp.dest(dest)) + .on('error', endErrorProcess); }); gulp.task('cordova:sync', function(cb) { @@ -503,7 +551,8 @@ gulp.task('cordova:sync', function(cb) { gulp.task('cordova', function() { return gulp.src('src/vendor/cordova/**/*') - .pipe(gulp.dest(path.join(config.dest, 'js/cordova'))); + .pipe(gulp.dest(path.join(config.dest, 'js/cordova'))) + .on('error', endErrorProcess); }); @@ -530,7 +579,9 @@ function buildManifest (env) { exclude: 'app.manifest', hash: true })) - .pipe(gulp.dest(config.dest)); + .on('error', endErrorProcess) + .pipe(gulp.dest(config.dest)) + .on('error', endErrorProcess); } gulp.task('manifest', function(){ From 87894a97fed241963010a296089980eadd8f2153 Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Tue, 20 Jun 2017 00:29:49 +0530 Subject: [PATCH 2/9] Added basic popover --- gulpfile.js | 1372 ++++++++++++++-------------- src/js/directives/pad.js | 534 ++++++----- src/js/services/pad/linkPreview.js | 35 + 3 files changed, 1017 insertions(+), 924 deletions(-) create mode 100644 src/js/services/pad/linkPreview.js diff --git a/gulpfile.js b/gulpfile.js index 1583a032..4280b2c1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -11,71 +11,71 @@ var config = { minifyImages: true, uglify: true, cssmin: true, - + vendor: { js: [ - './bower_components/jquery/dist/jquery.js', - './bower_components/selectize/dist/js/standalone/selectize.js', - './bower_components/modernizr/modernizr.js', - './bower_components/angular/angular.js', - './bower_components/angular-selectize2/dist/angular-selectize.js', - './bower_components/angular-route/angular-route.js', - './bower_components/angular-translate/angular-translate.js', - './bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js', - './bower_components/mobile-angular-ui/dist/js/mobile-angular-ui.js', - './bower_components/bootstrap-material-design/dist/js/material.js', - './bower_components/bootstrap-material-design/dist/js/ripples.js', - './bower_components/dropdown.js/jquery.dropdown.js', - './bower_components/angular-messages/angular-messages.js', - './bower_components/angular-bootstrap/ui-bootstrap-tpls.js', - './bower_components/angular-ui-notification/dist/angular-ui-notification.js', - './bower_components/angular-ui-layout/src/ui-layout.js', - './bower_components/autosize/dist/autosize.js', - './bower_components/angular-bindonce/bindonce.js', - './bower_components/angular-utf8-base64/angular-utf8-base64.js', - './bower_components/SHA-1/sha1.js', - './bower_components/angulartics/src/angulartics.js', - './bower_components/angulartics/src/angulartics-piwik.js', - './bower_components/angular-swellrt/dist/angular-swellrt.js', - './bower_components/hammerjs/hammer.js', - './bower_components/ryanmullins-angular-hammer/angular.hammer.js', - './bower_components/angular-sanitize/angular-sanitize.js', - './bower_components/angular-animate/angular-animate.js', - './bower_components/ngSticky/lib/sticky.js', - './bower_components/angular-toArrayFilter/toArrayFilter.js', - './bower_components/swiper/dist/js/swiper.js', - './bower_components/avatar/build/avatar.js', - './bower_components/avatar/vendor/md5.js', - './bower_components/moment/moment.js', - './bower_components/moment/locale/es.js', - './bower_components/angular-moment/angular-moment.js', - './bower_components/clipboard/dist/clipboard.js', - './bower_components/ngclipboard/dist/ngclipboard.js', - './bower_components/ng-img-crop-full-extended/compile/unminified/ng-img-crop.js', - './bower_components/ng-file-upload/ng-file-upload.js', - './bower_components/js-emoji/lib/emoji.js', - './bower_components/textfit/textFit.js', - './bower_components/angular-socialshare/dist/angular-socialshare.js', - './bower_components/webrtc-adapter/release/adapter.js', - './src/vendor/aggregation.js', - './src/vendor/startswith.js', - './node_modules/ng-infinite-scroll/build/ng-infinite-scroll.js' + './bower_components/jquery/dist/jquery.js', + './bower_components/selectize/dist/js/standalone/selectize.js', + './bower_components/modernizr/modernizr.js', + './bower_components/angular/angular.js', + './bower_components/angular-selectize2/dist/angular-selectize.js', + './bower_components/angular-route/angular-route.js', + './bower_components/angular-translate/angular-translate.js', + './bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js', + './bower_components/mobile-angular-ui/dist/js/mobile-angular-ui.js', + './bower_components/bootstrap-material-design/dist/js/material.js', + './bower_components/bootstrap-material-design/dist/js/ripples.js', + './bower_components/dropdown.js/jquery.dropdown.js', + './bower_components/angular-messages/angular-messages.js', + './bower_components/angular-bootstrap/ui-bootstrap-tpls.js', + './bower_components/angular-ui-notification/dist/angular-ui-notification.js', + './bower_components/angular-ui-layout/src/ui-layout.js', + './bower_components/autosize/dist/autosize.js', + './bower_components/angular-bindonce/bindonce.js', + './bower_components/angular-utf8-base64/angular-utf8-base64.js', + './bower_components/SHA-1/sha1.js', + './bower_components/angulartics/src/angulartics.js', + './bower_components/angulartics/src/angulartics-piwik.js', + './bower_components/angular-swellrt/dist/angular-swellrt.js', + './bower_components/hammerjs/hammer.js', + './bower_components/ryanmullins-angular-hammer/angular.hammer.js', + './bower_components/angular-sanitize/angular-sanitize.js', + './bower_components/angular-animate/angular-animate.js', + './bower_components/ngSticky/lib/sticky.js', + './bower_components/angular-toArrayFilter/toArrayFilter.js', + './bower_components/swiper/dist/js/swiper.js', + './bower_components/avatar/build/avatar.js', + './bower_components/avatar/vendor/md5.js', + './bower_components/moment/moment.js', + './bower_components/moment/locale/es.js', + './bower_components/angular-moment/angular-moment.js', + './bower_components/clipboard/dist/clipboard.js', + './bower_components/ngclipboard/dist/ngclipboard.js', + './bower_components/ng-img-crop-full-extended/compile/unminified/ng-img-crop.js', + './bower_components/ng-file-upload/ng-file-upload.js', + './bower_components/js-emoji/lib/emoji.js', + './bower_components/textfit/textFit.js', + './bower_components/angular-socialshare/dist/angular-socialshare.js', + './bower_components/webrtc-adapter/release/adapter.js', + './src/vendor/aggregation.js', + './src/vendor/startswith.js', + './node_modules/ng-infinite-scroll/build/ng-infinite-scroll.js' ], - + images: [ - './bower_components/emoji-data/sheet_apple_64.png', - 'src/images/**/*' + './bower_components/emoji-data/sheet_apple_64.png', + 'src/images/**/*' ], - + fonts: [ - './bower_components/material-design-icons/iconfont/MaterialIcons-Regular.ttf', - './bower_components/material-design-icons/iconfont/MaterialIcons-Regular.woff', - './bower_components/material-design-icons/iconfont/MaterialIcons-Regular.woff2', - './bower_components/font-awesome/fonts/fontawesome-webfont.*', - './src/fonts/*' + './bower_components/material-design-icons/iconfont/MaterialIcons-Regular.ttf', + './bower_components/material-design-icons/iconfont/MaterialIcons-Regular.woff', + './bower_components/material-design-icons/iconfont/MaterialIcons-Regular.woff2', + './bower_components/font-awesome/fonts/fontawesome-webfont.*', + './src/fonts/*' ] }, - + swellrt: { host: 'localhost:9898', protocol: 'http://', @@ -83,110 +83,110 @@ var config = { projectName: 'teem' } }, - + angularSwellrt: { path: './bower_components/angular-swellrt' }, - + /* - * Application Configuration - * - * Variables injected to AngularJs config value in src/js/app.js - * - * Example: - * config.app.support = { - * communityId: 'local.net/s+EWN1NKmVbsO', - * projectId: 'local.net/s+3WKINJhZMp8' - * }; - */ - app: { - }, - - /** - * Window Configuration - * - * Variables injected in window.* object. - */ - windowConfig: { - gMapsApiKey: 'AIzaSyDizEEZnUmbrB2DEX9iW4gpGzoLrpsLb3A' - }, - - // The default URL of the links - // Needed for HTML5 mode - base: '/', - - server: { - host: '0.0.0.0', - port: '8000' - }, - - serverTest: { - host: 'localhost', - port: '9001' - }, - - serverTestKarma: { - port: '8090' - }, - - weinre: false, - - piwik: false, - - deploy: { - files: { - branch: 'dist' + * Application Configuration + * + * Variables injected to AngularJs config value in src/js/app.js + * + * Example: + * config.app.support = { + * communityId: 'local.net/s+EWN1NKmVbsO', + * projectId: 'local.net/s+3WKINJhZMp8' + * }; + */ + app: { + }, + + /** + * Window Configuration + * + * Variables injected in window.* object. + */ + windowConfig: { + gMapsApiKey: 'AIzaSyDizEEZnUmbrB2DEX9iW4gpGzoLrpsLb3A' }, - swellrt: { - name: 'teem-swellrt', - config: '/usr/local/etc/docker-compose/teem-swellrt.yml' + + // The default URL of the links + // Needed for HTML5 mode + base: '/', + + server: { + host: '0.0.0.0', + port: '8000' + }, + + serverTest: { + host: 'localhost', + port: '9001' + }, + + serverTestKarma: { + port: '8090' + }, + + weinre: false, + + piwik: false, + + deploy: { + files: { + branch: 'dist' + }, + swellrt: { + name: 'teem-swellrt', + config: '/usr/local/etc/docker-compose/teem-swellrt.yml' + } } + }; + + + if (require('fs').existsSync('./config.js')) { + var configFn = require('./config'); + configFn(config); } -}; - - -if (require('fs').existsSync('./config.js')) { - var configFn = require('./config'); - configFn(config); -} - -// Build SwellRT url -if (! config.swellrt.server) { - config.swellrt.server = config.swellrt.protocol + config.swellrt.host; - if (config.swellrt.port) { - config.swellrt.server += ':' + config.swellrt.port; + + // Build SwellRT url + if (! config.swellrt.server) { + config.swellrt.server = config.swellrt.protocol + config.swellrt.host; + if (config.swellrt.port) { + config.swellrt.server += ':' + config.swellrt.port; + } } -} - -// Setup angular-swellrt stuff, depending on path -config.vendor.js.push(config.angularSwellrt.path + '/dist/angular-swellrt.js'); -config.angularSwellrt.swellrt = require(config.angularSwellrt.path + '/swellrt.json'); - -// Track SwellRT version in SwellRT config -// This way, clients are updated with the new SwellRT version -// despite the code does not change -config.swellrt.version = config.angularSwellrt.swellrt.version; - -// Fill docker options -if (config.swellrt.docker && !config.swellrt.docker.tag) { - config.swellrt.docker.tag = config.angularSwellrt.swellrt.version; -} - -if (config.deploy && !config.deploy.swellrt.tag) { - config.deploy.swellrt.tag = config.angularSwellrt.swellrt.version; -} - -// Use configuration in other modules, such as Karma -module.exports.config = config; - -/*----- End of Configuration ------*/ - - -/*======================================== -= Requiring stuffs = -========================================*/ - -var gulp = require('gulp'), + + // Setup angular-swellrt stuff, depending on path + config.vendor.js.push(config.angularSwellrt.path + '/dist/angular-swellrt.js'); + config.angularSwellrt.swellrt = require(config.angularSwellrt.path + '/swellrt.json'); + + // Track SwellRT version in SwellRT config + // This way, clients are updated with the new SwellRT version + // despite the code does not change + config.swellrt.version = config.angularSwellrt.swellrt.version; + + // Fill docker options + if (config.swellrt.docker && !config.swellrt.docker.tag) { + config.swellrt.docker.tag = config.angularSwellrt.swellrt.version; + } + + if (config.deploy && !config.deploy.swellrt.tag) { + config.deploy.swellrt.tag = config.angularSwellrt.swellrt.version; + } + + // Use configuration in other modules, such as Karma + module.exports.config = config; + + /*----- End of Configuration ------*/ + + + /*======================================== + = Requiring stuffs = + ========================================*/ + + var gulp = require('gulp'), gulpif = require('gulp-if'), seq = require('run-sequence'), connect = require('gulp-connect'), @@ -219,37 +219,37 @@ var gulp = require('gulp'), manifest = require('gulp-manifest'), spawn = require('child_process').spawn, gutil = require('gulp-util'); - - -/*=============================================== -= Handler for all the stream errors = -=================================================*/ -/** - * Logs the error occured in the pipe without killing the gulp process - * emits an end event to the corresponding stream - * @function endErrorProcess - * @param {Error} err - */ -function endErrorProcess(err){ - console.log(err); - this.emit('end'); -} - -/*================================================ -= Report Errors to Console = -================================================*/ - -gulp.on('error', function(e) { - throw(e); -}); - - -/*========================================= -= Clean dest folder = -=========================================*/ - -gulp.task('clean', function () { - return gulp.src([ + + + /*=============================================== + = Handler for all the stream errors = + =================================================*/ + /** + * Logs the error occured in the pipe without killing the gulp process + * emits an end event to the corresponding stream + * @function endErrorProcess + * @param {Error} err + */ + function endErrorProcess(err){ + console.log(err); + this.emit('end'); + } + + /*================================================ + = Report Errors to Console = + ================================================*/ + + gulp.on('error', function(e) { + throw(e); + }); + + + /*========================================= + = Clean dest folder = + =========================================*/ + + gulp.task('clean', function () { + return gulp.src([ path.join(config.dest, '*.html'), path.join(config.dest, 'images'), path.join(config.dest, 'css'), @@ -257,148 +257,148 @@ gulp.task('clean', function () { path.join(config.dest, 'fonts'), path.join(config.dest, 'l10n'), path.join(config.dest, 'app.manifest') - ], { read: false }) - .pipe(rimraf()) - .on('error', endErrorProcess); -}); - -gulp.task('clean:manifest', function () { - return gulp.src([ + ], { read: false }) + .pipe(rimraf()) + .on('error', endErrorProcess); + }); + + gulp.task('clean:manifest', function () { + return gulp.src([ path.join(config.dest, 'app.manifest') - ], { read: false }) - .pipe(rimraf()) - .on('error', endErrorProcess); -}); - - -/*========================================== -= Start a web server = -==========================================*/ - -gulp.task('connect', function() { - if (typeof config.server === 'object') { - connect.server({ - root: config.dest, - host: config.server.host, - port: config.server.port, - fallback: config.dest + '/index.html', - livereload: true - }); - } else { - throw new Error('Connect is not configured'); - } -}); - -/*============================================================== -= Setup live reloading on source changes = -==============================================================*/ - -gulp.task('livereload', function () { - gulp.src(path.join(config.dest, '*.html')) + ], { read: false }) + .pipe(rimraf()) + .on('error', endErrorProcess); + }); + + + /*========================================== + = Start a web server = + ==========================================*/ + + gulp.task('connect', function() { + if (typeof config.server === 'object') { + connect.server({ + root: config.dest, + host: config.server.host, + port: config.server.port, + fallback: config.dest + '/index.html', + livereload: true + }); + } else { + throw new Error('Connect is not configured'); + } + }); + + /*============================================================== + = Setup live reloading on source changes = + ==============================================================*/ + + gulp.task('livereload', function () { + gulp.src(path.join(config.dest, '*.html')) .pipe(connect.reload()) .on('error', endErrorProcess); -}); - - -/*===================================== -= Minify images = -=====================================*/ - -gulp.task('images', function () { - var stream = gulp.src(config.vendor.images); - - if (config.minifyImages) { - stream = stream.pipe(imagemin({ - progressive: true, - svgoPlugins: [{removeViewBox: false}], - use: [pngcrush()] - })) + }); + + + /*===================================== + = Minify images = + =====================================*/ + + gulp.task('images', function () { + var stream = gulp.src(config.vendor.images); + + if (config.minifyImages) { + stream = stream.pipe(imagemin({ + progressive: true, + svgoPlugins: [{removeViewBox: false}], + use: [pngcrush()] + })) + .on('error', endErrorProcess); + } + + return stream.pipe(gulp.dest(path.join(config.dest, 'images'))) .on('error', endErrorProcess); - } - - return stream.pipe(gulp.dest(path.join(config.dest, 'images'))) - .on('error', endErrorProcess); -}); - - -/*================================== -= Copy fonts = -==================================*/ - -gulp.task('fonts', function() { - return gulp.src(config.vendor.fonts) + }); + + + /*================================== + = Copy fonts = + ==================================*/ + + gulp.task('fonts', function() { + return gulp.src(config.vendor.fonts) .pipe(gulp.dest(path.join(config.dest, 'fonts'))) .on('error', endErrorProcess); -}); - -/*================================== -= Copy l10n = -==================================*/ - -gulp.task('l10n', function() { - return gulp.src('src/l10n/**/*') + }); + + /*================================== + = Copy l10n = + ==================================*/ + + gulp.task('l10n', function() { + return gulp.src('src/l10n/**/*') .pipe(gulp.dest(path.join(config.dest, 'l10n'))) .on('error', endErrorProcess); -}); - - -/*================================================= -= Copy html files to dest = -=================================================*/ -function buildHtml (env) { - var inject = []; - - inject.push(''); - - if(typeof config.windowConfig === 'object') { - inject.push(''); - } - - if (config.swellrt) { - let url; - - if (env === 'production') { - url = config.deploy.swellrt.remoteUrl; - } else { - url = config.swellrt.server; + }); + + + /*================================================= + = Copy html files to dest = + =================================================*/ + function buildHtml (env) { + var inject = []; + + inject.push(''); + + if(typeof config.windowConfig === 'object') { + inject.push(''); } - - inject.push(''); - inject.push(''); - } - - if (config.piwik && env === 'production') { - // Note that Angulartics needs that the trackPageView event from the original is removed - inject.push(''); - inject.push(''); - } - - if (typeof config.weinre === 'object') { - inject.push(''); - } - - return gulp.src(['src/html/**/*.html']) + + if (config.swellrt) { + let url; + + if (env === 'production') { + url = config.deploy.swellrt.remoteUrl; + } else { + url = config.swellrt.server; + } + + inject.push(''); + inject.push(''); + } + + if (config.piwik && env === 'production') { + // Note that Angulartics needs that the trackPageView event from the original is removed + inject.push(''); + inject.push(''); + } + + if (typeof config.weinre === 'object') { + inject.push(''); + } + + return gulp.src(['src/html/**/*.html']) .pipe(replace('', inject.join('\n '))) .on('error', endErrorProcess) .pipe(gulp.dest(config.dest)) .on('error', endErrorProcess); -} - -gulp.task('html', function() { - return buildHtml(); -}); - -// Rebuild html for production -gulp.task('html:production', function() { - return buildHtml('production'); -}); - -/*====================================================================== -= Compile, minify, mobilize Sass = -======================================================================*/ - -gulp.task('sass', function () { - gulp.src('./src/sass/app.sass') + } + + gulp.task('html', function() { + return buildHtml(); + }); + + // Rebuild html for production + gulp.task('html:production', function() { + return buildHtml('production'); + }); + + /*====================================================================== + = Compile, minify, mobilize Sass = + ======================================================================*/ + + gulp.task('sass', function () { + gulp.src('./src/sass/app.sass') .pipe(sourcemaps.init()) .on('error', endErrorProcess) .pipe(sass({ @@ -429,29 +429,29 @@ gulp.task('sass', function () { .on('error', endErrorProcess) .pipe(gulp.dest(path.join(config.dest, 'css'))) .on('error', endErrorProcess); -}); - -/*==================================================================== -= jshint = -====================================================================*/ - -gulp.task('jshint', function() { - return gulp.src('./src/js/**/*.js') + }); + + /*==================================================================== + = jshint = + ====================================================================*/ + + gulp.task('jshint', function() { + return gulp.src('./src/js/**/*.js') .pipe(jshint()) .on('error', endErrorProcess) .pipe(jshint.reporter('jshint-stylish')) .on('error', endErrorProcess); -}); - - -/*==================================================================== -= Compile and minify js generating source maps = -====================================================================*/ -// - Orders ng deps automatically -// - Precompile templates to ng templateCache - -gulp.task('js:app', function() { - return streamqueue({ objectMode: true }, + }); + + + /*==================================================================== + = Compile and minify js generating source maps = + ====================================================================*/ + // - Orders ng deps automatically + // - Precompile templates to ng templateCache + + gulp.task('js:app', function() { + return streamqueue({ objectMode: true }, // Vendor: angular, mobile-angular-ui, etc. gulp.src(config.vendor.js) .pipe(sourcemaps.init()) @@ -461,7 +461,7 @@ gulp.task('js:app', function() { .pipe(sourcemaps.init()) .on('error', endErrorProcess) .pipe(replace('value(\'config\', {}). // inject:app:config', - 'value(\'config\', ' + JSON.stringify(config.app) + ').')) + 'value(\'config\', ' + JSON.stringify(config.app) + ').')) .on('error', endErrorProcess) .pipe(babel({ presets: ['es2015'] @@ -486,322 +486,322 @@ gulp.task('js:app', function() { presets: ['es2015'] })) .on('error', endErrorProcess) - ) - .pipe(concat('app.js')) - .on('error', endErrorProcess) - .pipe(ngAnnotate()) - .on('error', endErrorProcess) - .pipe(gulpif(config.uglify, uglify())) - .on('error', endErrorProcess) - .pipe(rename({suffix: '.min'})) - .on('error', endErrorProcess) - .pipe(sourcemaps.write('.', { - sourceMappingURLPrefix: '/js/' - })) - .on('error', endErrorProcess) - .pipe(gulp.dest(path.join(config.dest, 'js'))) - .on('error', endErrorProcess); -}); - -gulp.task('js:widgets', function() { - return gulp.src('./src/js/widgets.js') - .pipe(uglify()) - .on('error', endErrorProcess) - .pipe(gulp.dest(path.join(config.dest, 'js'))) - .on('error', endErrorProcess); -}); - - -gulp.task('js', function(callback) { - var tasks = ['js:app', 'js:widgets']; - seq(tasks, callback); -}); - -/*================================== -= Cordova files = -==================================*/ - -// Sync files from local cordova folder -// Note that this needs having cordova platform android and related plugins -// installed -gulp.task('cordova:sync:clean', function() { - var dest = 'src/vendor/cordova'; - - return gulp.src([dest], - { read: false }) - .pipe(rimraf()) - .on('error', endErrorProcess); -}); - - -gulp.task('cordova:sync:copy', function() { - var source = 'cordova/platforms/android/assets/www/'; - var dest = 'src/vendor/cordova'; - - - return gulp.src([ source + '{cordova.js,cordova_plugins.js,plugins/**/*}']) + ) + .pipe(concat('app.js')) + .on('error', endErrorProcess) + .pipe(ngAnnotate()) + .on('error', endErrorProcess) + .pipe(gulpif(config.uglify, uglify())) + .on('error', endErrorProcess) + .pipe(rename({suffix: '.min'})) + .on('error', endErrorProcess) + .pipe(sourcemaps.write('.', { + sourceMappingURLPrefix: '/js/' + })) + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'js'))) + .on('error', endErrorProcess); + }); + + gulp.task('js:widgets', function() { + return gulp.src('./src/js/widgets.js') + .pipe(uglify()) + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'js'))) + .on('error', endErrorProcess); + }); + + + gulp.task('js', function(callback) { + var tasks = ['js:app', 'js:widgets']; + seq(tasks, callback); + }); + + /*================================== + = Cordova files = + ==================================*/ + + // Sync files from local cordova folder + // Note that this needs having cordova platform android and related plugins + // installed + gulp.task('cordova:sync:clean', function() { + var dest = 'src/vendor/cordova'; + + return gulp.src([dest], + { read: false }) + .pipe(rimraf()) + .on('error', endErrorProcess); + }); + + + gulp.task('cordova:sync:copy', function() { + var source = 'cordova/platforms/android/assets/www/'; + var dest = 'src/vendor/cordova'; + + + return gulp.src([ source + '{cordova.js,cordova_plugins.js,plugins/**/*}']) .pipe(gulp.dest(dest)) .on('error', endErrorProcess); -}); - -gulp.task('cordova:sync', function(cb) { - seq('cordova:sync:clean', 'cordova:sync:copy', cb); -}); - - -gulp.task('cordova', function() { - return gulp.src('src/vendor/cordova/**/*') + }); + + gulp.task('cordova:sync', function(cb) { + seq('cordova:sync:clean', 'cordova:sync:copy', cb); + }); + + + gulp.task('cordova', function() { + return gulp.src('src/vendor/cordova/**/*') .pipe(gulp.dest(path.join(config.dest, 'js/cordova'))) .on('error', endErrorProcess); -}); - - -/*=================================================================== -= Generate HTML5 Cache Manifest files = -===================================================================*/ - -function buildManifest (env) { - var files = [ + }); + + + /*=================================================================== + = Generate HTML5 Cache Manifest files = + ===================================================================*/ + + function buildManifest (env) { + var files = [ 'index.html', 'css/app.min.css', 'js/app.min.js' - ], - - swellrtUrl = env === 'production' ? config.deploy.swellrt.remoteUrl : config.swellrt.server; - - - return gulp.src(files.map(function(f) { return config.dest + '/' + f; }), { base: config.dest }) + ], + + swellrtUrl = env === 'production' ? config.deploy.swellrt.remoteUrl : config.swellrt.server; + + + return gulp.src(files.map(function(f) { return config.dest + '/' + f; }), { base: config.dest }) .pipe(manifest({ cache: [ - swellrtUrl + '/swellrt.js', - swellrtUrl + '/swellrt/swellrt.nocache.js' + swellrtUrl + '/swellrt.js', + swellrtUrl + '/swellrt/swellrt.nocache.js' ], exclude: 'app.manifest', hash: true })) .on('error', endErrorProcess) - .pipe(gulp.dest(config.dest)) - .on('error', endErrorProcess); -} - -gulp.task('manifest', function(){ - return buildManifest(); -}); - -gulp.task('manifest:production', function(){ - return buildManifest('production'); -}); -/*=================================================================== -= Watch for source changes and rebuild/reload = -===================================================================*/ - -gulp.task('watch', function () { - if (typeof config.server === 'object') { - watch([config.dest + '/**/*'], function() { gulp.start('livereload'); }); - } - watch(['./src/html/**/*'], function() { gulp.start('html'); }); - watch(['./src/sass/**/*'], function() { gulp.start('sass'); }); - watch(config.vendor.js.concat(['./src/js/**/*', './src/templates/**/*', '!./src/js/widgets.js']), function() { gulp.start(['jshint', 'js:app']); }); - watch(config.vendor.js.concat(['./src/js/widgets.js']), function() { gulp.start(['jshint', 'js:widgets']); }); - watch(['./src/images/**/*'], function() { gulp.start('images'); }); - watch(['./src/l10n/**/*'], function() { gulp.start('l10n'); }); - watch(['./swellrt/config/**/*'], function() { gulp.start('docker:swellrt:restart'); }); -}); - - -/*=================================================== -= Starts a Weinre Server = -===================================================*/ - -gulp.task('weinre', function() { - if (typeof config.weinre === 'object') { - var weinre = require('./node_modules/weinre/lib/weinre'); - weinre.run(config.weinre); - } else { - throw new Error('Weinre is not configured'); + .pipe(gulp.dest(config.dest)) + .on('error', endErrorProcess); } -}); - - -/*====================================== -= Build Sequence = -======================================*/ - -gulp.task('build', function(done) { - var tasks = ['html', 'fonts', 'l10n', 'images', 'sass', 'js', 'cordova']; - seq('clean', tasks, done); -}); - -/*==================================== -= Run SwellRT with Docker = -====================================*/ - -function dockerSwellrt (options, callback) { - - var args = [ '-p ' + config.swellrt.docker.projectName ]; - - if (options.args) { - Array.prototype.push.apply(args, options.args); + + gulp.task('manifest', function(){ + return buildManifest(); + }); + + gulp.task('manifest:production', function(){ + return buildManifest('production'); + }); + /*=================================================================== + = Watch for source changes and rebuild/reload = + ===================================================================*/ + + gulp.task('watch', function () { + if (typeof config.server === 'object') { + watch([config.dest + '/**/*'], function() { gulp.start('livereload'); }); + } + watch(['./src/html/**/*'], function() { gulp.start('html'); }); + watch(['./src/sass/**/*'], function() { gulp.start('sass'); }); + watch(config.vendor.js.concat(['./src/js/**/*', './src/templates/**/*', '!./src/js/widgets.js']), function() { gulp.start(['jshint', 'js:app']); }); + watch(config.vendor.js.concat(['./src/js/widgets.js']), function() { gulp.start(['jshint', 'js:widgets']); }); + watch(['./src/images/**/*'], function() { gulp.start('images'); }); + watch(['./src/l10n/**/*'], function() { gulp.start('l10n'); }); + watch(['./swellrt/config/**/*'], function() { gulp.start('docker:swellrt:restart'); }); + }); + + + /*=================================================== + = Starts a Weinre Server = + ===================================================*/ + + gulp.task('weinre', function() { + if (typeof config.weinre === 'object') { + var weinre = require('./node_modules/weinre/lib/weinre'); + weinre.run(config.weinre); + } else { + throw new Error('Weinre is not configured'); + } + }); + + + /*====================================== + = Build Sequence = + ======================================*/ + + gulp.task('build', function(done) { + var tasks = ['html', 'fonts', 'l10n', 'images', 'sass', 'js', 'cordova']; + seq('clean', tasks, done); + }); + + /*==================================== + = Run SwellRT with Docker = + ====================================*/ + + function dockerSwellrt (options, callback) { + + var args = [ '-p ' + config.swellrt.docker.projectName ]; + + if (options.args) { + Array.prototype.push.apply(args, options.args); + } + + // Set SwellRT version + process.env.SWELLRT_VERSION = config.swellrt.docker.tag; + + var child = spawn('docker-compose', args, { + cwd: process.cwd() + '/swellrt' + }), + stdout = '', + stderr = ''; + + child.stdout.on('data', (data) => { + + stdout += data; + gutil.log(gutil.colors.yellow(data)); + }); + + child.stderr.on('data', (data) => { + + stderr += data; + gutil.log(gutil.colors.yellow(data)); + }); + + child.on('close', () => { + + callback(); + }); } - - // Set SwellRT version - process.env.SWELLRT_VERSION = config.swellrt.docker.tag; - - var child = spawn('docker-compose', args, { - cwd: process.cwd() + '/swellrt' - }), - stdout = '', - stderr = ''; - - child.stdout.on('data', (data) => { - - stdout += data; - gutil.log(gutil.colors.yellow(data)); + + gulp.task('docker:swellrt', function(done) { + dockerSwellrt({ args: [ 'up', '-d' ]}, done); }); - - child.stderr.on('data', (data) => { - - stderr += data; - gutil.log(gutil.colors.yellow(data)); + + gulp.task('docker:swellrt:down', function(done) { + dockerSwellrt({ args: [ 'down' ]}, done); }); - - child.on('close', () => { - - callback(); + + gulp.task('docker:swellrt:restart', function(done) { + dockerSwellrt({ args: [ 'restart', 'swellrt' ]}, done); }); -} - -gulp.task('docker:swellrt', function(done) { - dockerSwellrt({ args: [ 'up', '-d' ]}, done); -}); - -gulp.task('docker:swellrt:down', function(done) { - dockerSwellrt({ args: [ 'down' ]}, done); -}); - -gulp.task('docker:swellrt:restart', function(done) { - dockerSwellrt({ args: [ 'restart', 'swellrt' ]}, done); -}); - - -/*====================================== -= Unit testing with Karma = -======================================*/ - -gulp.task('test:unit', function(done) { - new karma({ - configFile: __dirname + '/test/karma.conf.js', - singleRun: true - }, done).start(); -}); - -gulp.task('test:unit:loop', function(done) { - new karma({ - configFile: __dirname + '/test/karma.conf.js', - singleRun: false - }, done).start(); -}); - - -/*================================================ -= End to end testing with protractor = -=================================================*/ - -gulp.task('test:e2e', function(done) { - var tasks = [ 'test:e2e:protractor:install', 'test:e2e:protractor', done ]; - - if (config.swellrt.docker) { - tasks.unshift('docker:swellrt'); + + + /*====================================== + = Unit testing with Karma = + ======================================*/ + + gulp.task('test:unit', function(done) { + new karma({ + configFile: __dirname + '/test/karma.conf.js', + singleRun: true + }, done).start(); + }); + + gulp.task('test:unit:loop', function(done) { + new karma({ + configFile: __dirname + '/test/karma.conf.js', + singleRun: false + }, done).start(); + }); + + + /*================================================ + = End to end testing with protractor = + =================================================*/ + + gulp.task('test:e2e', function(done) { + var tasks = [ 'test:e2e:protractor:install', 'test:e2e:protractor', done ]; + + if (config.swellrt.docker) { + tasks.unshift('docker:swellrt'); + } + + seq.apply(this, tasks); + }); + + + function getProtractorBinary(binaryName){ + var winExt = /^win/.test(process.platform)? '.cmd' : ''; + var pkgPath = require.resolve('protractor'); + var protractorDir = path.resolve(path.join(path.dirname(pkgPath), '..', 'bin')); + + return path.join(protractorDir, '/' + binaryName+winExt); } - - seq.apply(this, tasks); -}); - - -function getProtractorBinary(binaryName){ - var winExt = /^win/.test(process.platform)? '.cmd' : ''; - var pkgPath = require.resolve('protractor'); - var protractorDir = path.resolve(path.join(path.dirname(pkgPath), '..', 'bin')); - - return path.join(protractorDir, '/' + binaryName+winExt); -} - -gulp.task('test:e2e:protractor:install', function(done){ - spawn(getProtractorBinary('webdriver-manager'), ['update'], { - stdio: 'inherit' - }).once('close', done); -}); - -// Run protractor from command line -gulp.task('test:e2e:protractor:run', function (done) { - var argv = process.argv.slice(3); // forward args to protractor - - spawn(getProtractorBinary('protractor'), argv, { - stdio: 'inherit' - }).once('close', done); -}); - - -gulp.task('test:e2e:protractor', function(done) { - var args = [ + + gulp.task('test:e2e:protractor:install', function(done){ + spawn(getProtractorBinary('webdriver-manager'), ['update'], { + stdio: 'inherit' + }).once('close', done); + }); + + // Run protractor from command line + gulp.task('test:e2e:protractor:run', function (done) { + var argv = process.argv.slice(3); // forward args to protractor + + spawn(getProtractorBinary('protractor'), argv, { + stdio: 'inherit' + }).once('close', done); + }); + + + gulp.task('test:e2e:protractor', function(done) { + var args = [ 'test/protractor.conf.js', '--baseUrl http://' + config.serverTest.host + ':' + config.serverTest.port, - ]; - - connect.server({ - root: config.dest, - host: config.serverTest.host, - port: config.serverTest.port, - fallback: config.dest + '/index.html' - }); - - spawn(getProtractorBinary('protractor'), args, { - stdio: 'inherit' - }) + ]; + + connect.server({ + root: config.dest, + host: config.serverTest.host, + port: config.serverTest.port, + fallback: config.dest + '/index.html' + }); + + spawn(getProtractorBinary('protractor'), args, { + stdio: 'inherit' + }) .once('close', function(code) { connect.serverClose(); - + if (code === 0) { done(); } else { throw 'Protractor error'; } }); - -}); - -/*==================================== -= Test Task = -====================================*/ - -gulp.task('test', function(done){ - var tasks = []; - - tasks.push('test:unit', 'test:e2e'); - - seq(tasks, done); -}); - -/*==================================== -= Deploy Task = -====================================*/ - -gulp.task('deploy:swellrt', function(done) { - var connection = new ssh(); - - connection.on('ready', function() { - var cmd = 'SWELLRT_VERSION=' + config.deploy.swellrt.tag + - ' docker-compose -f ' + config.deploy.swellrt.config + - ' -p ' + config.deploy.swellrt.name + - ' up -d'; - - console.log(cmd); - - connection.exec(cmd, function(err, stream) { - - if (err) { throw err ; } - - stream. + + }); + + /*==================================== + = Test Task = + ====================================*/ + + gulp.task('test', function(done){ + var tasks = []; + + tasks.push('test:unit', 'test:e2e'); + + seq(tasks, done); + }); + + /*==================================== + = Deploy Task = + ====================================*/ + + gulp.task('deploy:swellrt', function(done) { + var connection = new ssh(); + + connection.on('ready', function() { + var cmd = 'SWELLRT_VERSION=' + config.deploy.swellrt.tag + + ' docker-compose -f ' + config.deploy.swellrt.config + + ' -p ' + config.deploy.swellrt.name + + ' up -d'; + + console.log(cmd); + + connection.exec(cmd, function(err, stream) { + + if (err) { throw err ; } + + stream. on('data', function(d) { console.log('ssh: ' + d); }). @@ -810,70 +810,70 @@ gulp.task('deploy:swellrt', function(done) { connection.end(); }). stderr.on('data', function(data) { console.log('STDERR: ' + data); }); - }); - }).connect(config.deploy.swellrt.ssh); -}); - -gulp.task('deploy:files', function(done) { - ghPages.publish(path.join(__dirname, config.dest), - config.deploy.files, - done); -}); - -gulp.task('deploy', function(done) { - var tasks = ['deploy:swellrt', 'deploy:files']; - - seq('html:production', 'manifest:production', tasks, done); -}); - - -/*============================================ -= Continous Delivery Task = -============================================*/ - -gulp.task('cd', function(done) { - seq('build', 'test', 'deploy', done); -}); - -/*============================================ -= Staging task = -= Always deploy and pass specs afterwards = -============================================*/ - -gulp.task('cd:pushAndRun', function(done) { - seq('build', 'deploy', [ 'clean:manifest', 'html' ], 'test', done); -}); - -/*============================================ -= Build and test = -= Other branches just build and test = -============================================*/ - -gulp.task('buildAndTest', function(done) { - seq('build', 'test', done); -}); - - -/*==================================== -= Default Task = -====================================*/ - -gulp.task('default', function(done){ - var tasks = []; - - if (config.swellrt.docker) { - tasks.push('docker:swellrt'); - } - - if (typeof config.weinre === 'object') { - tasks.push('weinre'); - } - - if (typeof config.server === 'object') { - tasks.push('connect'); - } - - tasks.push('watch'); - - seq('build', tasks, done); -}); + }); + }).connect(config.deploy.swellrt.ssh); + }); + + gulp.task('deploy:files', function(done) { + ghPages.publish(path.join(__dirname, config.dest), + config.deploy.files, + done); + }); + + gulp.task('deploy', function(done) { + var tasks = ['deploy:swellrt', 'deploy:files']; + + seq('html:production', 'manifest:production', tasks, done); + }); + + + /*============================================ + = Continous Delivery Task = + ============================================*/ + + gulp.task('cd', function(done) { + seq('build', 'test', 'deploy', done); + }); + + /*============================================ + = Staging task = + = Always deploy and pass specs afterwards = + ============================================*/ + + gulp.task('cd:pushAndRun', function(done) { + seq('build', 'deploy', [ 'clean:manifest', 'html' ], 'test', done); + }); + + /*============================================ + = Build and test = + = Other branches just build and test = + ============================================*/ + + gulp.task('buildAndTest', function(done) { + seq('build', 'test', done); + }); + + + /*==================================== + = Default Task = + ====================================*/ + + gulp.task('default', function(done){ + var tasks = []; + + if (config.swellrt.docker) { + tasks.push('docker:swellrt'); + } + + if (typeof config.weinre === 'object') { + tasks.push('weinre'); + } + + if (typeof config.server === 'object') { + tasks.push('connect'); + } + + tasks.push('watch'); + + seq('build', tasks, done); + }); \ No newline at end of file diff --git a/src/js/directives/pad.js b/src/js/directives/pad.js index 8133d0f1..854cd19d 100644 --- a/src/js/directives/pad.js +++ b/src/js/directives/pad.js @@ -1,254 +1,312 @@ 'use strict'; /** - * @ngdoc function - * @name Teem.controller:ChatCtrl - * @description - * # Chat Ctrl - * Show Pad for a given project - */ - +* @ngdoc function +* @name Teem.controller:ChatCtrl +* @description +* # Chat Ctrl +* Show Pad for a given project +*/ angular.module('Teem') - .directive('pad', function() { - return { - scope: true, - link: function($scope, elem, attrs) { - $scope.editingDefault = attrs.editingDefault; - }, - controller: [ - 'SessionSvc', '$rootScope', '$scope', '$route', '$location', - '$timeout', 'SharedState', 'needWidget', '$element', - function(SessionSvc, $rootScope, $scope, $route, $location, - $timeout, SharedState, needWidget, $element) { - - var buttons = ['text_fields', 'format_bold', 'format_italic', 'format_strikethrough', - 'format_align_left', 'format_align_center', 'format_align_right', - 'format_list_bulleted', 'format_list_numbered']; - - var annotationMap = { - 'text_fields': 'paragraph/header=h3', - 'format_bold': 'style/fontWeight=bold', - 'format_italic': 'style/fontStyle=italic', - 'format_strikethrough': 'style/textDecoration=line-through', - 'format_align_left': 'paragraph/textAlign=left', - 'format_align_center': 'paragraph/textAlign=center', - 'format_align_right': 'paragraph/textAlign=right', - 'format_list_bulleted': 'paragraph/listStyleType=unordered', - 'format_list_numbered': 'paragraph/listStyleType=decimal' - }; - - var annotations = {}; - - function imgWidget(parentElement, before, state) { - state = state || before; - - if (!(state in $scope.project.attachments) || !$scope.project.attachments[state].file) { - return; - } - - // cannot use spinner template directly here - parentElement.innerHTML = ` -
-
- - - -
-
`; - - $scope.project.attachments[state].file.getUrl().then(url => { - parentElement.innerHTML = ``; - }); +.directive('pad', function() { + return { + scope: true, + link: function($scope, elem, attrs) { + $scope.editingDefault = attrs.editingDefault; + }, + controller: [ + 'SessionSvc', '$rootScope', '$scope', '$route', '$location', + '$timeout', 'SharedState', 'needWidget', '$element','linkPreview', + function(SessionSvc, $rootScope, $scope, $route, $location, + $timeout, SharedState, needWidget, $element, linkPreview) { + + var buttons = ['text_fields', 'format_bold', 'format_italic', 'format_strikethrough', + 'format_align_left', 'format_align_center', 'format_align_right', + 'format_list_bulleted', 'format_list_numbered']; + + var annotationMap = { + 'text_fields': 'paragraph/header=h3', + 'format_bold': 'style/fontWeight=bold', + 'format_italic': 'style/fontStyle=italic', + 'format_strikethrough': 'style/textDecoration=line-through', + 'format_align_left': 'paragraph/textAlign=left', + 'format_align_center': 'paragraph/textAlign=center', + 'format_align_right': 'paragraph/textAlign=right', + 'format_list_bulleted': 'paragraph/listStyleType=unordered', + 'format_list_numbered': 'paragraph/listStyleType=decimal' + }; + + var annotations = {}; + + function imgWidget(parentElement, before, state) { + state = state || before; + + if (!(state in $scope.project.attachments) || !$scope.project.attachments[state].file) { + return; + } + + // cannot use spinner template directly here + parentElement.innerHTML = ` +
+
+ + + +
+
`; + + $scope.project.attachments[state].file.getUrl().then(url => { + parentElement.innerHTML = ``; + }); + } + + $scope.padWidgets = { + 'need': needWidget.getWidget($scope), + 'img': { + onInit: imgWidget, + onChangeState: imgWidget + } + }; + + $scope.padAnnotations = { + 'paragraph/header': { + onAdd: function() { + $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); + $timeout(); + }, + onChange: function() { + $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); + $timeout(); + }, + onRemove: function() { + $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); + $timeout(); } - - $scope.padWidgets = { - 'need': needWidget.getWidget($scope), - 'img': { - onInit: imgWidget, - onChangeState: imgWidget + }, + 'link': { + onEvent: function(range, event) { + let timer; + let div = document.createElement('div'); + if (event.type === 'click') { + event.stopPropagation(); + $scope.linkModal.open(range); + div.style.display = 'none'; + clearTimeout(timer); } - }; - - $scope.padAnnotations = { - 'paragraph/header': { - onAdd: function() { - $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); - $timeout(); - }, - onChange: function() { - $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); - $timeout(); - }, - onRemove: function() { - $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); - $timeout(); - } - }, - 'link': { - onEvent: function(range, event) { - if (event.type === 'click') { - event.stopPropagation(); - $scope.linkModal.open(range); - } - } + else if(event.type === 'mouseover'){ + timer = setTimeout(() => { + console.log(event); + event.stopPropagation(); + let btn = event.target; + console.dir(btn.offsetHeight); + let inHTML = ` + Loading.... + `; + linkPreview.getMetaData(btn.href) + .then((meta) => { + console.log(meta); + if(!meta){ + div.style.display = 'none'; + return; + } + let urlDate = meta.date, + urlImage = meta.image, + urlAuthor = meta.author, + urlLink = meta.url, + urlTitle = meta.title, + urlDescription = meta.description, + urlPublisher = meta.title; + if(urlImage){ + // div.style.backgroundImage = `url(${urlImage})`; + // div.style.filter = 'grayscale(1)'; + } + if(urlDescription){ + pStyle = 'position: absolute; bottom: 5px;width:100%'; + div.innerHTML = `

${urlDescription}

`; + } + }) + .catch((err) => { + console.log(err); + }); + div.innerHTML = inHTML; + div.style.width = '350px'; + div.style.height = '250px'; + div.style.position = 'absolute'; + div.style.border = '1px solid #F0F0F0'; + div.style.left = event.clientX - event.target.offsetWidth/2 - 20 + 'px'; + div.style.top = event.clientY + event.target.offsetTop/2 - 10 + 'px'; + div.style.zIndex = 3; + div.style.backgroundColor = '#F2F2F2'; + div.id = 'popover'; + div.style.padding = '10px'; + document.body.appendChild(div); + },500); } - }; - - function updateAllButtons() { - for (let btn of buttons) { - let [key, val] = annotationMap[btn].split('='); - $scope.buttons[btn] = (annotations && annotations[key] === val); + else if(event.type === 'mouseout'){ + clearTimeout(timer); + setTimeout(() => { + document.body.removeChild(document.getElementById('popover')); + }, 500); } - $timeout(); } + } + }; + + function updateAllButtons() { + for (let btn of buttons) { + let [key, val] = annotationMap[btn].split('='); + $scope.buttons[btn] = (annotations && annotations[key] === val); + } + $timeout(); + } + + function disableAllButtons() { + $scope.buttons = {}; + buttons.forEach(btn => $scope.buttons[btn] = false); + $timeout(); + } + + $scope.padCreate = function(editor) { + + $scope.linkModal = { + add: function(event) { + event.stopPropagation(); + let range = editor.getSelection(); + if (range.text) { + editor.setAnnotation('link', ''); + } + $scope.linkModal.open(range); + }, + open: function(range) { + let annotation = editor.getAnnotationInRange(range, 'link'); + + $scope.linkModal.range = range; + $scope.linkModal.annotation = annotation; + console.log(range); + let clientRect = range.node.nextSibling ? + range.node.nextSibling.getBoundingClientRect() : + range.node.parentElement.getBoundingClientRect(); + document.getElementById('link-modal').style.top = clientRect.top + 25 + 'px'; + document.getElementById('link-modal').style.left = clientRect.left + 'px'; + + $scope.linkModal.text = range.text; + $scope.linkModal.link = annotation ? annotation.value : ''; + $scope.linkModal.show = true; + + let emptyInput = !range.text ? 'text': 'link'; + let autofocus = document.querySelector('#link-modal [ng-model="linkModal.' + emptyInput + '"]'); + $timeout(() => autofocus && autofocus.focus()); + }, + change: function() { + let range = editor.setText($scope.linkModal.range, $scope.linkModal.text); + editor.setAnnotationInRange(range, 'link', $scope.linkModal.link); + $scope.linkModal.show = false; + $scope.linkModal.edit = false; + }, + clear: function() { + editor.clearAnnotationInRange($scope.linkModal.range, 'link'); + $scope.linkModal.show = false; + $scope.linkModal.edit = false; + } + }; - function disableAllButtons() { - $scope.buttons = {}; - buttons.forEach(btn => $scope.buttons[btn] = false); - $timeout(); + disableAllButtons(); + + editor.onSelectionChanged(function(range) { + annotations = range.annotations; + updateAllButtons(); + }); + }; + + $scope.padReady = function(editor) { + // FIXME + // SwellRT editor is created with .wave-editor-off + // Should use .wave-editor-on when SwellRT editor callback is available + // https://github.com/P2Pvalue/swellrt/issues/84 + var editorElement = angular.element($element.find('.swellrt-editor').children()[0]); + + editorElement.on('focus', updateAllButtons); + editorElement.on('blur', disableAllButtons); + + $scope.pad.outline = editor.getAnnotationSet('paragraph/header'); + + $scope.annotate = function(btn) { + let [key, val] = annotationMap[btn].split('='); + let currentVal = annotations[key]; + if (currentVal === val) { + val = null; } - $scope.padCreate = function(editor) { + annotations[key] = val; + editor.setAnnotation(key, val); + editorElement.focus(); + }; - $scope.linkModal = { - add: function(event) { - event.stopPropagation(); - let range = editor.getSelection(); - if (range.text) { - editor.setAnnotation('link', ''); - } - $scope.linkModal.open(range); - }, - open: function(range) { - let annotation = editor.getAnnotationInRange(range, 'link'); - - $scope.linkModal.range = range; - $scope.linkModal.annotation = annotation; - console.log(range); - let clientRect = range.node.nextSibling ? - range.node.nextSibling.getBoundingClientRect() : - range.node.parentElement.getBoundingClientRect(); - document.getElementById('link-modal').style.top = clientRect.top + 25 + 'px'; - document.getElementById('link-modal').style.left = clientRect.left + 'px'; - - $scope.linkModal.text = range.text; - $scope.linkModal.link = annotation ? annotation.value : ''; - $scope.linkModal.show = true; - - let emptyInput = !range.text ? 'text': 'link'; - let autofocus = document.querySelector('#link-modal [ng-model="linkModal.' + emptyInput + '"]'); - $timeout(() => autofocus && autofocus.focus()); - }, - change: function() { - let range = editor.setText($scope.linkModal.range, $scope.linkModal.text); - editor.setAnnotationInRange(range, 'link', $scope.linkModal.link); - $scope.linkModal.show = false; - $scope.linkModal.edit = false; - }, - clear: function() { - editor.clearAnnotationInRange($scope.linkModal.range, 'link'); - $scope.linkModal.show = false; - $scope.linkModal.edit = false; - } - }; - - disableAllButtons(); - - editor.onSelectionChanged(function(range) { - annotations = range.annotations; - updateAllButtons(); - }); - }; - - $scope.padReady = function(editor) { - // FIXME - // SwellRT editor is created with .wave-editor-off - // Should use .wave-editor-on when SwellRT editor callback is available - // https://github.com/P2Pvalue/swellrt/issues/84 - var editorElement = angular.element($element.find('.swellrt-editor').children()[0]); - - editorElement.on('focus', updateAllButtons); - editorElement.on('blur', disableAllButtons); - - $scope.pad.outline = editor.getAnnotationSet('paragraph/header'); - - $scope.annotate = function(btn) { - let [key, val] = annotationMap[btn].split('='); - let currentVal = annotations[key]; - if (currentVal === val) { - val = null; - } - - annotations[key] = val; - editor.setAnnotation(key, val); - editorElement.focus(); - }; - - $scope.clearFormat = function() { - editor.clearAnnotation('style'); - editorElement.focus(); - }; - - $scope.widget = function(type) { - if (type === 'need') { - needWidget.add(editor, $scope); - } - if (type === 'img') { - if (arguments[1] === undefined) { // First step - $scope.pad.selectingFile = true; - $timeout(() => $scope.pad.selectingFile = false); - } else { // Second step - $scope.pad.selectingFile = false; - var id = $scope.project.addAttachment(arguments[1]); - editor.addWidget('img', id); - } - } - }; - - $scope.editOn = function () { - if (editorElement.attr('class') === 'wave-editor-on') { - $scope.pad.editing = true; - SessionSvc.showSaving = true; - SharedState.turnOn('hiddenTabs'); - $timeout(); - } - }; - - $scope.editOff = function () { - if (editorElement.attr('class') === 'wave-editor-on') { - $scope.pad.editing = $scope.editingDefault; - SessionSvc.showSaving = false; - SharedState.turnOff('hiddenTabs'); - $timeout(); - } - }; - - if ($scope.editingDefault && $scope.project.isParticipant()) { - $scope.pad.editing = true; - } + $scope.clearFormat = function() { + editor.clearAnnotation('style'); + editorElement.focus(); + }; - // FIXME We should get the pad text directly from the editor, but - // I couldn't find the proper way - if ($scope.project.isParticipant() && $scope.project.pad.text() === '') { - $scope.pad.emptyTip = true; + $scope.widget = function(type) { + if (type === 'need') { + needWidget.add(editor, $scope); + } + if (type === 'img') { + if (arguments[1] === undefined) { // First step + $scope.pad.selectingFile = true; + $timeout(() => $scope.pad.selectingFile = false); + } else { // Second step + $scope.pad.selectingFile = false; + var id = $scope.project.addAttachment(arguments[1]); + editor.addWidget('img', id); } + } + }; + + $scope.editOn = function () { + if (editorElement.attr('class') === 'wave-editor-on') { + $scope.pad.editing = true; + SessionSvc.showSaving = true; + SharedState.turnOn('hiddenTabs'); + $timeout(); + } + }; - }; - - $scope.$watchCollection(function() { - return SessionSvc.status; - }, function(current) { - $scope.pad.saving = !current.sync; - }); - - $scope.closePadEmptyTip = function closePadEmptyTip() { - $scope.pad.emptyTip = false; - $timeout(() => { - angular.element(document.querySelector('.wave-editor-on')).focus(); - }); - }; - - }], - templateUrl: 'pad.html' - }; - }); + $scope.editOff = function () { + if (editorElement.attr('class') === 'wave-editor-on') { + $scope.pad.editing = $scope.editingDefault; + SessionSvc.showSaving = false; + SharedState.turnOff('hiddenTabs'); + $timeout(); + } + }; + + if ($scope.editingDefault && $scope.project.isParticipant()) { + $scope.pad.editing = true; + } + + // FIXME We should get the pad text directly from the editor, but + // I couldn't find the proper way + if ($scope.project.isParticipant() && $scope.project.pad.text() === '') { + $scope.pad.emptyTip = true; + } + + }; + + $scope.$watchCollection(function() { + return SessionSvc.status; + }, function(current) { + $scope.pad.saving = !current.sync; + }); + + $scope.closePadEmptyTip = function closePadEmptyTip() { + $scope.pad.emptyTip = false; + $timeout(() => { + angular.element(document.querySelector('.wave-editor-on')).focus(); + }); + }; + + }], + templateUrl: 'pad.html' + }; +}); diff --git a/src/js/services/pad/linkPreview.js b/src/js/services/pad/linkPreview.js new file mode 100644 index 00000000..ac4d2cf4 --- /dev/null +++ b/src/js/services/pad/linkPreview.js @@ -0,0 +1,35 @@ +(function() { + 'use strict'; + + + /** + * @module Teem + * @method linkPreview + * @param {String} url + * Returns the parsed meta data of the given link + */ + + angular + .module('Teem') + .factory('linkPreview', linkPreview); + + function linkPreview($http) { + const LINK_PREVIEW_SERVER_URL = 'http://localhost:9090/fetch'; + function getMetaData(url){ + //TODO: implement a check for the URL to be correct + if(!url) return; + return $http.post(LINK_PREVIEW_SERVER_URL,{url}) + .then((res) => { + return res.data; + }) + .catch((err) => { + console.log(err); + }); + } + + return { + getMetaData + }; + } + linkPreview.$inject = ['$http']; +})(); \ No newline at end of file From 9dd4e638b267d56ab50cb9585a175c63e8d56a4b Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Tue, 20 Jun 2017 21:41:36 +0530 Subject: [PATCH 3/9] Some changes in the popover --- src/js/directives/pad.js | 169 +++++++++++++++++++++++++++------------ 1 file changed, 116 insertions(+), 53 deletions(-) diff --git a/src/js/directives/pad.js b/src/js/directives/pad.js index 854cd19d..fdd3ae63 100644 --- a/src/js/directives/pad.js +++ b/src/js/directives/pad.js @@ -7,6 +7,7 @@ * # Chat Ctrl * Show Pad for a given project */ +let timer,styleAppended = false; angular.module('Teem') .directive('pad', function() { return { @@ -25,7 +26,7 @@ angular.module('Teem') 'format_list_bulleted', 'format_list_numbered']; var annotationMap = { - 'text_fields': 'paragraph/header=h3', + 'text_fields': 'paragraph/header=h3', 'format_bold': 'style/fontWeight=bold', 'format_italic': 'style/fontStyle=italic', 'format_strikethrough': 'style/textDecoration=line-through', @@ -38,6 +39,118 @@ angular.module('Teem') var annotations = {}; + function openLinkPopover(event){ + if(!styleAppended){ + let pStyle = document.createElement('style'); + pStyle.innerHTML = ` + #popover{ + width: 330px; + height: 270px; + margin: 0 5px; + border-radius: 6px; + } + div.popover-link-image{ + width: 330px; + height: 190px; + margin: 5px auto; + } + div.popover-link-description{ + width: 320px; + height: auto; + max-height: 40px; + margin: 0 auto; + overflow: auto; + word-wrap: break-all; + } + .popover-link-address{ + color: #000; + margin-left: 5px; + } + .popover-link-title{ + margin-left: 5px; + }`; + document.body.appendChild(pStyle); + styleAppended = true; + } + timer = $timeout(() => { + console.log(event); + event.stopPropagation(); + let div = document.createElement('div'); + let btn = event.target; + console.dir(btn.offsetHeight); + let inHTML = ` + Loading.... + `; + linkPreview.getMetaData(btn.href) + .then((meta) => { + console.log(meta); + if(!meta){ + div.style.display = 'none'; + return; + } + let urlImage = meta.image, + urlAuthor = meta.author, + urlTitle = meta.title, + urlDescription = meta.description; + if(urlImage && urlDescription){ + inHTML = `
+ + + + ${btn.href} +
`; + } + else if(urlDescription && !urlImage){ + inHTML = `
+ + + ${btn.href} +
`; + } + else{ + div.style.height = '110px'; + inHTML = `
+ + + ${btn.href} +
`; + } + div.innerHTML = inHTML; + }) + .catch((err) => { + console.log(err); + }); + div.innerHTML = inHTML; + div.style.width = '345px'; + div.style.height = '300px'; + div.style.position = 'absolute'; + div.style.border = '1px solid #F0F0F0'; + div.style.left = event.clientX - event.target.offsetWidth/2 - 20 + 'px'; + div.style.top = event.clientY + 50 + 'px'; + div.style.zIndex = 3; + div.style.backgroundColor = '#F2F2F2'; + div.style.paddingTop = '5px'; + div.id = 'popover-container'; + document.body.appendChild(div); + },500); + } + + function closeLinkPopover(event){ + console.log(event); + if(timer){ + $timeout.cancel(timer); + timer = null; + $timeout(() => { + document.body.removeChild(document.getElementById('popover-container')); + }, 500); + } + } + function imgWidget(parentElement, before, state) { state = state || before; @@ -85,7 +198,6 @@ angular.module('Teem') }, 'link': { onEvent: function(range, event) { - let timer; let div = document.createElement('div'); if (event.type === 'click') { event.stopPropagation(); @@ -94,59 +206,10 @@ angular.module('Teem') clearTimeout(timer); } else if(event.type === 'mouseover'){ - timer = setTimeout(() => { - console.log(event); - event.stopPropagation(); - let btn = event.target; - console.dir(btn.offsetHeight); - let inHTML = ` - Loading.... - `; - linkPreview.getMetaData(btn.href) - .then((meta) => { - console.log(meta); - if(!meta){ - div.style.display = 'none'; - return; - } - let urlDate = meta.date, - urlImage = meta.image, - urlAuthor = meta.author, - urlLink = meta.url, - urlTitle = meta.title, - urlDescription = meta.description, - urlPublisher = meta.title; - if(urlImage){ - // div.style.backgroundImage = `url(${urlImage})`; - // div.style.filter = 'grayscale(1)'; - } - if(urlDescription){ - pStyle = 'position: absolute; bottom: 5px;width:100%'; - div.innerHTML = `

${urlDescription}

`; - } - }) - .catch((err) => { - console.log(err); - }); - div.innerHTML = inHTML; - div.style.width = '350px'; - div.style.height = '250px'; - div.style.position = 'absolute'; - div.style.border = '1px solid #F0F0F0'; - div.style.left = event.clientX - event.target.offsetWidth/2 - 20 + 'px'; - div.style.top = event.clientY + event.target.offsetTop/2 - 10 + 'px'; - div.style.zIndex = 3; - div.style.backgroundColor = '#F2F2F2'; - div.id = 'popover'; - div.style.padding = '10px'; - document.body.appendChild(div); - },500); + openLinkPopover(event); } else if(event.type === 'mouseout'){ - clearTimeout(timer); - setTimeout(() => { - document.body.removeChild(document.getElementById('popover')); - }, 500); + closeLinkPopover(event); } } } From a5e7980c1372a12710176296029d346b6c485992 Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Thu, 22 Jun 2017 17:01:47 +0530 Subject: [PATCH 4/9] Added some stable changes to popover --- src/js/directives/pad.js | 508 +++++++++++++++++++++------------------ 1 file changed, 276 insertions(+), 232 deletions(-) diff --git a/src/js/directives/pad.js b/src/js/directives/pad.js index fdd3ae63..adb961b7 100644 --- a/src/js/directives/pad.js +++ b/src/js/directives/pad.js @@ -9,37 +9,37 @@ */ let timer,styleAppended = false; angular.module('Teem') -.directive('pad', function() { - return { - scope: true, - link: function($scope, elem, attrs) { - $scope.editingDefault = attrs.editingDefault; - }, - controller: [ - 'SessionSvc', '$rootScope', '$scope', '$route', '$location', - '$timeout', 'SharedState', 'needWidget', '$element','linkPreview', - function(SessionSvc, $rootScope, $scope, $route, $location, - $timeout, SharedState, needWidget, $element, linkPreview) { - - var buttons = ['text_fields', 'format_bold', 'format_italic', 'format_strikethrough', - 'format_align_left', 'format_align_center', 'format_align_right', - 'format_list_bulleted', 'format_list_numbered']; - - var annotationMap = { + .directive('pad', function() { + return { + scope: true, + link: function($scope, elem, attrs) { + $scope.editingDefault = attrs.editingDefault; + }, + controller: [ + 'SessionSvc', '$rootScope', '$scope', '$route', '$location', + '$timeout', 'SharedState', 'needWidget', '$element','linkPreview', + function(SessionSvc, $rootScope, $scope, $route, $location, + $timeout, SharedState, needWidget, $element, linkPreview) { + + var buttons = ['text_fields', 'format_bold', 'format_italic', 'format_strikethrough', + 'format_align_left', 'format_align_center', 'format_align_right', + 'format_list_bulleted', 'format_list_numbered']; + + var annotationMap = { 'text_fields': 'paragraph/header=h3', - 'format_bold': 'style/fontWeight=bold', - 'format_italic': 'style/fontStyle=italic', - 'format_strikethrough': 'style/textDecoration=line-through', - 'format_align_left': 'paragraph/textAlign=left', - 'format_align_center': 'paragraph/textAlign=center', - 'format_align_right': 'paragraph/textAlign=right', - 'format_list_bulleted': 'paragraph/listStyleType=unordered', - 'format_list_numbered': 'paragraph/listStyleType=decimal' - }; - - var annotations = {}; - - function openLinkPopover(event){ + 'format_bold': 'style/fontWeight=bold', + 'format_italic': 'style/fontStyle=italic', + 'format_strikethrough': 'style/textDecoration=line-through', + 'format_align_left': 'paragraph/textAlign=left', + 'format_align_center': 'paragraph/textAlign=center', + 'format_align_right': 'paragraph/textAlign=right', + 'format_list_bulleted': 'paragraph/listStyleType=unordered', + 'format_list_numbered': 'paragraph/listStyleType=decimal' + }; + + var annotations = {}; + + function openLinkPopover(event,range){ if(!styleAppended){ let pStyle = document.createElement('style'); pStyle.innerHTML = ` @@ -65,21 +65,58 @@ angular.module('Teem') .popover-link-address{ color: #000; margin-left: 5px; + overflow: auto; + word-wrap: break-all; + text-overflow: ellipsis; + white-space: nowrap; } .popover-link-title{ margin-left: 5px; + } + #popover-container:after{ + content: ""; + position: absolute; + bottom: -25px; + left: 175px; + border-style: solid; + visibility: hidden; + width: 0; + z-index: 1; + } + #popover-container:before{ + content: ""; + position: absolute; + top: -11px; + left: -1px; + border-style: solid; + border-width: 0 10px 10px; + border-color: #F1F1F1 transparent; + display: block; + width: 0; + z-index: 0; }`; document.body.appendChild(pStyle); styleAppended = true; } timer = $timeout(() => { - console.log(event); event.stopPropagation(); let div = document.createElement('div'); let btn = event.target; console.dir(btn.offsetHeight); let inHTML = ` - Loading.... + +
+
+ + + +
+
`; linkPreview.getMetaData(btn.href) .then((meta) => { @@ -89,35 +126,40 @@ angular.module('Teem') return; } let urlImage = meta.image, - urlAuthor = meta.author, - urlTitle = meta.title, - urlDescription = meta.description; + urlAuthor = meta.author, + urlTitle = meta.title, + urlDescription = meta.description; if(urlImage && urlDescription){ inHTML = `
- - ${btn.href} + +
`; } else if(urlDescription && !urlImage){ + div.style.height = '110px'; inHTML = `
- ${btn.href} +
`; } else{ + if(!urlTitle){ + div.style.height = '110px'; + inHTML = `
+ + +
`; + } div.style.height = '110px'; inHTML = `
- ${btn.href} +
`; } div.innerHTML = inHTML; @@ -130,24 +172,27 @@ angular.module('Teem') div.style.height = '300px'; div.style.position = 'absolute'; div.style.border = '1px solid #F0F0F0'; - div.style.left = event.clientX - event.target.offsetWidth/2 - 20 + 'px'; - div.style.top = event.clientY + 50 + 'px'; + let clientRect = range.node.nextSibling ? + range.node.nextSibling.getBoundingClientRect() : + range.node.parentElement.getBoundingClientRect(); + div.style.top = clientRect.top + 35 + 'px'; + div.style.left = clientRect.left + 'px'; div.style.zIndex = 3; div.style.backgroundColor = '#F2F2F2'; div.style.paddingTop = '5px'; div.id = 'popover-container'; document.body.appendChild(div); - },500); + },700); } - function closeLinkPopover(event){ - console.log(event); + function closeLinkPopover(delay){ if(timer){ $timeout.cancel(timer); timer = null; $timeout(() => { - document.body.removeChild(document.getElementById('popover-container')); - }, 500); + if(document.getElementById('popover-container')) + document.body.removeChild(document.getElementById('popover-container')); + }, delay); } } @@ -158,218 +203,217 @@ angular.module('Teem') return; } - // cannot use spinner template directly here - parentElement.innerHTML = ` -
-
- - - -
-
`; - - $scope.project.attachments[state].file.getUrl().then(url => { - parentElement.innerHTML = ``; - }); - } - - $scope.padWidgets = { - 'need': needWidget.getWidget($scope), - 'img': { - onInit: imgWidget, - onChangeState: imgWidget + // cannot use spinner template directly here + parentElement.innerHTML = ` +
+
+ + + +
+
`; + + $scope.project.attachments[state].file.getUrl().then(url => { + parentElement.innerHTML = ``; + }); } - }; - $scope.padAnnotations = { - 'paragraph/header': { - onAdd: function() { - $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); - $timeout(); - }, - onChange: function() { - $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); - $timeout(); - }, - onRemove: function() { - $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); - $timeout(); + $scope.padWidgets = { + 'need': needWidget.getWidget($scope), + 'img': { + onInit: imgWidget, + onChangeState: imgWidget } - }, - 'link': { - onEvent: function(range, event) { - let div = document.createElement('div'); - if (event.type === 'click') { - event.stopPropagation(); - $scope.linkModal.open(range); - div.style.display = 'none'; - clearTimeout(timer); - } - else if(event.type === 'mouseover'){ - openLinkPopover(event); + }; + + $scope.padAnnotations = { + 'paragraph/header': { + onAdd: function() { + $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); + $timeout(); + }, + onChange: function() { + $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); + $timeout(); + }, + onRemove: function() { + $scope.pad.outline = this.editor.getAnnotationSet('paragraph/header'); + $timeout(); } - else if(event.type === 'mouseout'){ - closeLinkPopover(event); + }, + 'link': { + onEvent: function(range, event) { + if (event.type === 'click') { + event.stopPropagation(); + closeLinkPopover(0); + $scope.linkModal.open(range); + } + else if(event.type === 'mouseover'){ + openLinkPopover(event,range); + console.log(range); + } + else if(event.type === 'mouseout'){ + closeLinkPopover(500); + } } } - } - }; + }; - function updateAllButtons() { - for (let btn of buttons) { - let [key, val] = annotationMap[btn].split('='); - $scope.buttons[btn] = (annotations && annotations[key] === val); + function updateAllButtons() { + for (let btn of buttons) { + let [key, val] = annotationMap[btn].split('='); + $scope.buttons[btn] = (annotations && annotations[key] === val); + } + $timeout(); } - $timeout(); - } - function disableAllButtons() { - $scope.buttons = {}; - buttons.forEach(btn => $scope.buttons[btn] = false); - $timeout(); - } + function disableAllButtons() { + $scope.buttons = {}; + buttons.forEach(btn => $scope.buttons[btn] = false); + $timeout(); + } - $scope.padCreate = function(editor) { + $scope.padCreate = function(editor) { - $scope.linkModal = { - add: function(event) { - event.stopPropagation(); - let range = editor.getSelection(); - if (range.text) { - editor.setAnnotation('link', ''); + $scope.linkModal = { + add: function(event) { + event.stopPropagation(); + let range = editor.getSelection(); + if (range.text) { + editor.setAnnotation('link', ''); + } + $scope.linkModal.open(range); + }, + open: function(range) { + let annotation = editor.getAnnotationInRange(range, 'link'); + + $scope.linkModal.range = range; + $scope.linkModal.annotation = annotation; + console.log(range); + let clientRect = range.node.nextSibling ? + range.node.nextSibling.getBoundingClientRect() : + range.node.parentElement.getBoundingClientRect(); + document.getElementById('link-modal').style.top = clientRect.top + 25 + 'px'; + document.getElementById('link-modal').style.left = clientRect.left + 'px'; + + $scope.linkModal.text = range.text; + $scope.linkModal.link = annotation ? annotation.value : ''; + $scope.linkModal.show = true; + + let emptyInput = !range.text ? 'text': 'link'; + let autofocus = document.querySelector('#link-modal [ng-model="linkModal.' + emptyInput + '"]'); + $timeout(() => autofocus && autofocus.focus()); + }, + change: function() { + let range = editor.setText($scope.linkModal.range, $scope.linkModal.text); + editor.setAnnotationInRange(range, 'link', $scope.linkModal.link); + $scope.linkModal.show = false; + $scope.linkModal.edit = false; + }, + clear: function() { + editor.clearAnnotationInRange($scope.linkModal.range, 'link'); + $scope.linkModal.show = false; + $scope.linkModal.edit = false; } - $scope.linkModal.open(range); - }, - open: function(range) { - let annotation = editor.getAnnotationInRange(range, 'link'); - - $scope.linkModal.range = range; - $scope.linkModal.annotation = annotation; - console.log(range); - let clientRect = range.node.nextSibling ? - range.node.nextSibling.getBoundingClientRect() : - range.node.parentElement.getBoundingClientRect(); - document.getElementById('link-modal').style.top = clientRect.top + 25 + 'px'; - document.getElementById('link-modal').style.left = clientRect.left + 'px'; - - $scope.linkModal.text = range.text; - $scope.linkModal.link = annotation ? annotation.value : ''; - $scope.linkModal.show = true; - - let emptyInput = !range.text ? 'text': 'link'; - let autofocus = document.querySelector('#link-modal [ng-model="linkModal.' + emptyInput + '"]'); - $timeout(() => autofocus && autofocus.focus()); - }, - change: function() { - let range = editor.setText($scope.linkModal.range, $scope.linkModal.text); - editor.setAnnotationInRange(range, 'link', $scope.linkModal.link); - $scope.linkModal.show = false; - $scope.linkModal.edit = false; - }, - clear: function() { - editor.clearAnnotationInRange($scope.linkModal.range, 'link'); - $scope.linkModal.show = false; - $scope.linkModal.edit = false; - } - }; + }; - disableAllButtons(); + disableAllButtons(); - editor.onSelectionChanged(function(range) { - annotations = range.annotations; - updateAllButtons(); - }); - }; + editor.onSelectionChanged(function(range) { + annotations = range.annotations; + updateAllButtons(); + }); + }; - $scope.padReady = function(editor) { - // FIXME - // SwellRT editor is created with .wave-editor-off - // Should use .wave-editor-on when SwellRT editor callback is available - // https://github.com/P2Pvalue/swellrt/issues/84 - var editorElement = angular.element($element.find('.swellrt-editor').children()[0]); + $scope.padReady = function(editor) { + // FIXME + // SwellRT editor is created with .wave-editor-off + // Should use .wave-editor-on when SwellRT editor callback is available + // https://github.com/P2Pvalue/swellrt/issues/84 + var editorElement = angular.element($element.find('.swellrt-editor').children()[0]); - editorElement.on('focus', updateAllButtons); - editorElement.on('blur', disableAllButtons); + editorElement.on('focus', updateAllButtons); + editorElement.on('blur', disableAllButtons); - $scope.pad.outline = editor.getAnnotationSet('paragraph/header'); + $scope.pad.outline = editor.getAnnotationSet('paragraph/header'); - $scope.annotate = function(btn) { - let [key, val] = annotationMap[btn].split('='); - let currentVal = annotations[key]; - if (currentVal === val) { - val = null; - } + $scope.annotate = function(btn) { + let [key, val] = annotationMap[btn].split('='); + let currentVal = annotations[key]; + if (currentVal === val) { + val = null; + } - annotations[key] = val; - editor.setAnnotation(key, val); - editorElement.focus(); - }; + annotations[key] = val; + editor.setAnnotation(key, val); + editorElement.focus(); + }; - $scope.clearFormat = function() { - editor.clearAnnotation('style'); - editorElement.focus(); - }; + $scope.clearFormat = function() { + editor.clearAnnotation('style'); + editorElement.focus(); + }; - $scope.widget = function(type) { - if (type === 'need') { - needWidget.add(editor, $scope); - } - if (type === 'img') { - if (arguments[1] === undefined) { // First step - $scope.pad.selectingFile = true; - $timeout(() => $scope.pad.selectingFile = false); - } else { // Second step - $scope.pad.selectingFile = false; - var id = $scope.project.addAttachment(arguments[1]); - editor.addWidget('img', id); + $scope.widget = function(type) { + if (type === 'need') { + needWidget.add(editor, $scope); } - } - }; + if (type === 'img') { + if (arguments[1] === undefined) { // First step + $scope.pad.selectingFile = true; + $timeout(() => $scope.pad.selectingFile = false); + } else { // Second step + $scope.pad.selectingFile = false; + var id = $scope.project.addAttachment(arguments[1]); + editor.addWidget('img', id); + } + } + }; + + $scope.editOn = function () { + if (editorElement.attr('class') === 'wave-editor-on') { + $scope.pad.editing = true; + SessionSvc.showSaving = true; + SharedState.turnOn('hiddenTabs'); + $timeout(); + } + }; + + $scope.editOff = function () { + if (editorElement.attr('class') === 'wave-editor-on') { + $scope.pad.editing = $scope.editingDefault; + SessionSvc.showSaving = false; + SharedState.turnOff('hiddenTabs'); + $timeout(); + } + }; - $scope.editOn = function () { - if (editorElement.attr('class') === 'wave-editor-on') { + if ($scope.editingDefault && $scope.project.isParticipant()) { $scope.pad.editing = true; - SessionSvc.showSaving = true; - SharedState.turnOn('hiddenTabs'); - $timeout(); } - }; - $scope.editOff = function () { - if (editorElement.attr('class') === 'wave-editor-on') { - $scope.pad.editing = $scope.editingDefault; - SessionSvc.showSaving = false; - SharedState.turnOff('hiddenTabs'); - $timeout(); + // FIXME We should get the pad text directly from the editor, but + // I couldn't find the proper way + if ($scope.project.isParticipant() && $scope.project.pad.text() === '') { + $scope.pad.emptyTip = true; } - }; - - if ($scope.editingDefault && $scope.project.isParticipant()) { - $scope.pad.editing = true; - } - - // FIXME We should get the pad text directly from the editor, but - // I couldn't find the proper way - if ($scope.project.isParticipant() && $scope.project.pad.text() === '') { - $scope.pad.emptyTip = true; - } - - }; - $scope.$watchCollection(function() { - return SessionSvc.status; - }, function(current) { - $scope.pad.saving = !current.sync; - }); + }; - $scope.closePadEmptyTip = function closePadEmptyTip() { - $scope.pad.emptyTip = false; - $timeout(() => { - angular.element(document.querySelector('.wave-editor-on')).focus(); + $scope.$watchCollection(function() { + return SessionSvc.status; + }, function(current) { + $scope.pad.saving = !current.sync; }); - }; - }], - templateUrl: 'pad.html' - }; + $scope.closePadEmptyTip = function closePadEmptyTip() { + $scope.pad.emptyTip = false; + $timeout(() => { + angular.element(document.querySelector('.wave-editor-on')).focus(); + }); + }; + + }], + templateUrl: 'pad.html' + }; }); From 46b44a9b5a6d8f76c063cc9805fc258e9389919f Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Thu, 22 Jun 2017 17:34:50 +0530 Subject: [PATCH 5/9] separating bug fixes --- gulpfile.js | 88 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index fdd99d4f..229d989e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -220,7 +220,16 @@ var gulp = require('gulp'), spawn = require('child_process').spawn, gutil = require('gulp-util'); - +/** +* Logs the error occured in the pipe without killing the gulp process +* emits an end event to the corresponding stream +* @function endErrorProcess +* @param {Error} err +*/ +function endErrorProcess(err){ + console.log(err); + this.emit('end'); +} /*================================================ = Report Errors to Console = ================================================*/ @@ -244,14 +253,16 @@ gulp.task('clean', function () { path.join(config.dest, 'l10n'), path.join(config.dest, 'app.manifest') ], { read: false }) - .pipe(rimraf()); + .pipe(rimraf()) + .on('error', endErrorProcess); }); gulp.task('clean:manifest', function () { return gulp.src([ path.join(config.dest, 'app.manifest') ], { read: false }) - .pipe(rimraf()); + .pipe(rimraf()) + .on('error', endErrorProcess); }); @@ -279,7 +290,8 @@ gulp.task('connect', function() { gulp.task('livereload', function () { gulp.src(path.join(config.dest, '*.html')) - .pipe(connect.reload()); + .pipe(connect.reload()) + .on('error', endErrorProcess); }); @@ -295,10 +307,12 @@ gulp.task('images', function () { progressive: true, svgoPlugins: [{removeViewBox: false}], use: [pngcrush()] - })); + })) + .on('error', endErrorProcess); } - return stream.pipe(gulp.dest(path.join(config.dest, 'images'))); + return stream.pipe(gulp.dest(path.join(config.dest, 'images'))) + .on('error', endErrorProcess); }); @@ -308,7 +322,8 @@ gulp.task('images', function () { gulp.task('fonts', function() { return gulp.src(config.vendor.fonts) - .pipe(gulp.dest(path.join(config.dest, 'fonts'))); + .pipe(gulp.dest(path.join(config.dest, 'fonts'))) + .on('error', endErrorProcess); }); /*================================== @@ -317,7 +332,8 @@ gulp.task('fonts', function() { gulp.task('l10n', function() { return gulp.src('src/l10n/**/*') - .pipe(gulp.dest(path.join(config.dest, 'l10n'))); + .pipe(gulp.dest(path.join(config.dest, 'l10n'))) + .on('error', endErrorProcess); }); @@ -358,7 +374,9 @@ function buildHtml (env) { return gulp.src(['src/html/**/*.html']) .pipe(replace('', inject.join('\n '))) - .pipe(gulp.dest(config.dest)); + .on('error', endErrorProcess) + .pipe(gulp.dest(config.dest)) + .on('error', endErrorProcess); } gulp.task('html', function() { @@ -377,10 +395,12 @@ gulp.task('html:production', function() { gulp.task('sass', function () { gulp.src('./src/sass/app.sass') .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(sass({ includePaths: [ path.resolve(__dirname, 'src/sass'), path.resolve(__dirname, 'bower_components'), path.resolve(__dirname, 'bower_components/bootstrap-sass/assets/stylesheets') ] }).on('error', sass.logError)) .pipe(postcss([ autoprefixer({ browsers: ['last 2 versions', 'Android >= 4'] }) ])) + .on('error', endErrorProcess) /* Currently not working with sourcemaps .pipe(mobilizer('app.css', { 'app.css': { @@ -394,11 +414,15 @@ gulp.task('sass', function () { })) */ .pipe(gulpif(config.cssmin, cssmin())) + .on('error', endErrorProcess) .pipe(rename({suffix: '.min'})) + .on('error', endErrorProcess) .pipe(sourcemaps.write('.', { sourceMappingURLPrefix: '/css/' })) - .pipe(gulp.dest(path.join(config.dest, 'css'))); + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'css'))) + .on('error', endErrorProcess); }); /*==================================================================== @@ -408,7 +432,9 @@ gulp.task('sass', function () { gulp.task('jshint', function() { return gulp.src('./src/js/**/*.js') .pipe(jshint()) - .pipe(jshint.reporter('jshint-stylish')); + .on('error', endErrorProcess) + .pipe(jshint.reporter('jshint-stylish')) + .on('error', endErrorProcess); }); @@ -422,44 +448,61 @@ gulp.task('js:app', function() { return streamqueue({ objectMode: true }, // Vendor: angular, mobile-angular-ui, etc. gulp.src(config.vendor.js) - .pipe(sourcemaps.init()), + .pipe(sourcemaps.init()) + .on('error', endErrorProcess), // app.js is configured gulp.src('./src/js/app.js') .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(replace('value(\'config\', {}). // inject:app:config', 'value(\'config\', ' + JSON.stringify(config.app) + ').')) + .on('error', endErrorProcess) .pipe(babel({ presets: ['es2015'] - })), + })) + .on('error', endErrorProcess), // rest of app logic gulp.src(['./src/js/**/*.js', '!./src/js/app.js', '!./src/js/widgets.js']) .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(babel({ presets: ['es2015'], plugins: ['transform-object-assign'] })) - .pipe(ngFilesort()), + .on('error', endErrorProcess) + .pipe(ngFilesort()) + .on('error', endErrorProcess), // app templates gulp.src(['src/templates/**/*.html']).pipe(templateCache({ module: 'Teem' })) .pipe(sourcemaps.init()) + .on('error', endErrorProcess) .pipe(babel({ presets: ['es2015'] })) + .on('error', endErrorProcess) ) .pipe(concat('app.js')) + .on('error', endErrorProcess) .pipe(ngAnnotate()) + .on('error', endErrorProcess) .pipe(gulpif(config.uglify, uglify())) + .on('error', endErrorProcess) .pipe(rename({suffix: '.min'})) + .on('error', endErrorProcess) .pipe(sourcemaps.write('.', { sourceMappingURLPrefix: '/js/' })) - .pipe(gulp.dest(path.join(config.dest, 'js'))); + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'js'))) + .on('error', endErrorProcess); }); gulp.task('js:widgets', function() { return gulp.src('./src/js/widgets.js') .pipe(uglify()) - .pipe(gulp.dest(path.join(config.dest, 'js'))); + .on('error', endErrorProcess) + .pipe(gulp.dest(path.join(config.dest, 'js'))) + .on('error', endErrorProcess); }); @@ -481,7 +524,8 @@ gulp.task('cordova:sync:clean', function() { return gulp.src([dest], { read: false }) - .pipe(rimraf()); + .pipe(rimraf()) + .on('error', endErrorProcess); }); @@ -493,7 +537,8 @@ gulp.task('cordova:sync:copy', function() { return gulp.src([ source + '{cordova.js,cordova_plugins.js,plugins/**/*}']) - .pipe(gulp.dest(dest)); + .pipe(gulp.dest(dest)) + .on('error', endErrorProcess); }); gulp.task('cordova:sync', function(cb) { @@ -503,7 +548,8 @@ gulp.task('cordova:sync', function(cb) { gulp.task('cordova', function() { return gulp.src('src/vendor/cordova/**/*') - .pipe(gulp.dest(path.join(config.dest, 'js/cordova'))); + .pipe(gulp.dest(path.join(config.dest, 'js/cordova'))) + .on('error', endErrorProcess); }); @@ -530,7 +576,9 @@ function buildManifest (env) { exclude: 'app.manifest', hash: true })) - .pipe(gulp.dest(config.dest)); + .on('error', endErrorProcess) + .pipe(gulp.dest(config.dest)) + .on('error', endErrorProcess); } gulp.task('manifest', function(){ From 16881d76eedb49f08ea52903d6c9d4b0824dc4c4 Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Thu, 22 Jun 2017 19:09:31 +0530 Subject: [PATCH 6/9] Removed jshint warnings --- src/js/directives/pad.js | 11 ++++-- src/js/services/pad/linkPreview.js | 54 ++++++++++++++++-------------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/js/directives/pad.js b/src/js/directives/pad.js index adb961b7..693bb846 100644 --- a/src/js/directives/pad.js +++ b/src/js/directives/pad.js @@ -62,6 +62,12 @@ angular.module('Teem') overflow: auto; word-wrap: break-all; } + .popover-link-title{ + word-wrap: break-all; + text-overflow: ellpsis; + overflow: hidden; + white-space: nowrap; + } .popover-link-address{ color: #000; margin-left: 5px; @@ -153,7 +159,7 @@ angular.module('Teem') inHTML = `
-
`; + `; } div.style.height = '110px'; inHTML = `
@@ -190,8 +196,9 @@ angular.module('Teem') $timeout.cancel(timer); timer = null; $timeout(() => { - if(document.getElementById('popover-container')) + if(document.getElementById('popover-container')){ document.body.removeChild(document.getElementById('popover-container')); + } }, delay); } } diff --git a/src/js/services/pad/linkPreview.js b/src/js/services/pad/linkPreview.js index ac4d2cf4..1d7a0284 100644 --- a/src/js/services/pad/linkPreview.js +++ b/src/js/services/pad/linkPreview.js @@ -2,34 +2,36 @@ 'use strict'; - /** - * @module Teem - * @method linkPreview - * @param {String} url - * Returns the parsed meta data of the given link - */ +/** + * @module Teem + * @method linkPreview + * @param {String} url + * Returns the parsed meta data of the given link + */ - angular - .module('Teem') - .factory('linkPreview', linkPreview); +let linkPreviewFactory = angular.module('Teem'); - function linkPreview($http) { - const LINK_PREVIEW_SERVER_URL = 'http://localhost:9090/fetch'; - function getMetaData(url){ - //TODO: implement a check for the URL to be correct - if(!url) return; - return $http.post(LINK_PREVIEW_SERVER_URL,{url}) - .then((res) => { - return res.data; - }) - .catch((err) => { - console.log(err); - }); + +function linkPreview($http) { + const LINK_PREVIEW_SERVER_URL = 'http://localhost:9090/fetch'; + function getMetaData(url){ + //TODO: implement a check for the URL to be correct + if(!url){ + return; } + return $http.post(LINK_PREVIEW_SERVER_URL,{url}) + .then((res) => { + return res.data; + }) + .catch((err) => { + console.log(err); + }); + } - return { - getMetaData - }; - } - linkPreview.$inject = ['$http']; + return { + getMetaData + }; +} +linkPreview.$inject = ['$http']; +linkPreviewFactory.factory('linkPreview', linkPreview); })(); \ No newline at end of file From 997258f2b85d98bdc1207792d0f0296eb0189308 Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Fri, 23 Jun 2017 20:17:32 +0530 Subject: [PATCH 7/9] Added automatic pull of teemlp docker image --- src/js/directives/pad.js | 6 +++--- swellrt/docker-compose.yml | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/js/directives/pad.js b/src/js/directives/pad.js index 693bb846..2d01812b 100644 --- a/src/js/directives/pad.js +++ b/src/js/directives/pad.js @@ -173,14 +173,14 @@ angular.module('Teem') .catch((err) => { console.log(err); }); + let clientRect = range.node.nextSibling ? + range.node.nextSibling.getBoundingClientRect() : + range.node.parentElement.getBoundingClientRect(); div.innerHTML = inHTML; div.style.width = '345px'; div.style.height = '300px'; div.style.position = 'absolute'; div.style.border = '1px solid #F0F0F0'; - let clientRect = range.node.nextSibling ? - range.node.nextSibling.getBoundingClientRect() : - range.node.parentElement.getBoundingClientRect(); div.style.top = clientRect.top + 35 + 'px'; div.style.left = clientRect.left + 'px'; div.style.zIndex = 3; diff --git a/swellrt/docker-compose.yml b/swellrt/docker-compose.yml index 32d8367f..65cb8dbb 100644 --- a/swellrt/docker-compose.yml +++ b/swellrt/docker-compose.yml @@ -15,6 +15,11 @@ services: mongo: image: mongo:latest restart: always + teem-link-preview: + image: krshubham/teem-link-preview:latest + restart: always + ports: + - "0.0.0.0:9090:9090" From 188abec77dfcc51228c17cc8fb9512016fbc8c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Tenorio=20Forn=C3=A9s?= Date: Wed, 16 Aug 2017 18:41:16 +0200 Subject: [PATCH 8/9] update secrets --- .travis/before_script.sh | 2 +- .travis/secrets.tar.enc | Bin 10256 -> 10256 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/before_script.sh b/.travis/before_script.sh index 1d62dad7..a7d85c78 100755 --- a/.travis/before_script.sh +++ b/.travis/before_script.sh @@ -9,7 +9,7 @@ fi if [ $TRAVIS_BRANCH = "master" ] || [ $TRAVIS_BRANCH = "staging" ]; then echo "Using config.js for branch $TRAVIS_BRANCH" - openssl aes-256-cbc -K $encrypted_f03f2d3a9637_key -iv $encrypted_f03f2d3a9637_iv -in .travis/secrets.tar.enc -out .travis/secrets.tar -d + openssl aes-256-cbc -K $encrypted_249e297d6459_key -iv $encrypted_249e297d6459_iv -in .travis/secrets.tar.enc -out .travis/secrets.tar -d tar xvf .travis/secrets.tar --directory .travis diff --git a/.travis/secrets.tar.enc b/.travis/secrets.tar.enc index e24ba777fc1d93b77eadd07df8466ff27825ff40..a192d49a9b0818dfc5973cfabe204e7a476ef42f 100644 GIT binary patch literal 10256 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 literal 10256 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 From dada231249619c43ecacaa99659638ec34c5f250 Mon Sep 17 00:00:00 2001 From: Kumar Shubham Date: Wed, 30 Aug 2017 00:11:31 +0530 Subject: [PATCH 9/9] some final corrections added --- src/js/directives/pad.js | 650 ++++++++++++++++++--------------------- src/sass/pad.sass | 65 +++- src/templates/pad.html | 44 ++- 3 files changed, 398 insertions(+), 361 deletions(-) diff --git a/src/js/directives/pad.js b/src/js/directives/pad.js index 2d01812b..60b97a38 100644 --- a/src/js/directives/pad.js +++ b/src/js/directives/pad.js @@ -1,115 +1,51 @@ 'use strict'; /** -* @ngdoc function -* @name Teem.controller:ChatCtrl -* @description -* # Chat Ctrl -* Show Pad for a given project -*/ -let timer,styleAppended = false; + * @ngdoc function + * @name Teem.controller:ChatCtrl + * @description + * # Chat Ctrl + * Show Pad for a given project + */ +let timer; angular.module('Teem') - .directive('pad', function() { + .directive('pad', function () { return { scope: true, - link: function($scope, elem, attrs) { + link: function ($scope, elem, attrs) { $scope.editingDefault = attrs.editingDefault; }, controller: [ - 'SessionSvc', '$rootScope', '$scope', '$route', '$location', - '$timeout', 'SharedState', 'needWidget', '$element','linkPreview', - function(SessionSvc, $rootScope, $scope, $route, $location, - $timeout, SharedState, needWidget, $element, linkPreview) { - - var buttons = ['text_fields', 'format_bold', 'format_italic', 'format_strikethrough', - 'format_align_left', 'format_align_center', 'format_align_right', - 'format_list_bulleted', 'format_list_numbered']; - - var annotationMap = { - 'text_fields': 'paragraph/header=h3', - 'format_bold': 'style/fontWeight=bold', - 'format_italic': 'style/fontStyle=italic', - 'format_strikethrough': 'style/textDecoration=line-through', - 'format_align_left': 'paragraph/textAlign=left', - 'format_align_center': 'paragraph/textAlign=center', - 'format_align_right': 'paragraph/textAlign=right', - 'format_list_bulleted': 'paragraph/listStyleType=unordered', - 'format_list_numbered': 'paragraph/listStyleType=decimal' - }; - - var annotations = {}; - - function openLinkPopover(event,range){ - if(!styleAppended){ - let pStyle = document.createElement('style'); - pStyle.innerHTML = ` - #popover{ - width: 330px; - height: 270px; - margin: 0 5px; - border-radius: 6px; - } - div.popover-link-image{ - width: 330px; - height: 190px; - margin: 5px auto; - } - div.popover-link-description{ - width: 320px; - height: auto; - max-height: 40px; - margin: 0 auto; - overflow: auto; - word-wrap: break-all; - } - .popover-link-title{ - word-wrap: break-all; - text-overflow: ellpsis; - overflow: hidden; - white-space: nowrap; - } - .popover-link-address{ - color: #000; - margin-left: 5px; - overflow: auto; - word-wrap: break-all; - text-overflow: ellipsis; - white-space: nowrap; - } - .popover-link-title{ - margin-left: 5px; - } - #popover-container:after{ - content: ""; - position: absolute; - bottom: -25px; - left: 175px; - border-style: solid; - visibility: hidden; - width: 0; - z-index: 1; - } - #popover-container:before{ - content: ""; - position: absolute; - top: -11px; - left: -1px; - border-style: solid; - border-width: 0 10px 10px; - border-color: #F1F1F1 transparent; - display: block; - width: 0; - z-index: 0; - }`; - document.body.appendChild(pStyle); - styleAppended = true; - } - timer = $timeout(() => { - event.stopPropagation(); - let div = document.createElement('div'); - let btn = event.target; - console.dir(btn.offsetHeight); - let inHTML = ` + 'SessionSvc', '$rootScope', '$scope', '$route', '$location', + '$timeout', 'SharedState', 'needWidget', '$element', 'linkPreview', + function (SessionSvc, $rootScope, $scope, $route, $location, + $timeout, SharedState, needWidget, $element, linkPreview) { + + var buttons = ['text_fields', 'format_bold', 'format_italic', 'format_strikethrough', + 'format_align_left', 'format_align_center', 'format_align_right', + 'format_list_bulleted', 'format_list_numbered']; + + var annotationMap = { + 'text_fields': 'paragraph/header=h3', + 'format_bold': 'style/fontWeight=bold', + 'format_italic': 'style/fontStyle=italic', + 'format_strikethrough': 'style/textDecoration=line-through', + 'format_align_left': 'paragraph/textAlign=left', + 'format_align_center': 'paragraph/textAlign=center', + 'format_align_right': 'paragraph/textAlign=right', + 'format_list_bulleted': 'paragraph/listStyleType=unordered', + 'format_list_numbered': 'paragraph/listStyleType=decimal' + }; + + var annotations = {}; + + function openLinkPopover(event, range) { + timer = $timeout(() => { + event.stopPropagation(); + let div = document.createElement('div'); + let btn = event.target; + //cannot inject the spinner HTML directly here + let inHTML = `