diff --git a/app/controllers/forms.server.controller.js b/app/controllers/forms.server.controller.js index 3ba7a214..d3fd64fc 100644 --- a/app/controllers/forms.server.controller.js +++ b/app/controllers/forms.server.controller.js @@ -81,10 +81,14 @@ exports.createSubmission = function(req, res) { async.waterfall([ function(callback) { - if (form.selfNotifications && form.selfNotifications.enabled && form.selfNotifications.fromField) { - form.selfNotifications.fromEmails = formFieldDict[form.selfNotifications.fromField]; - - emailNotifications.send(form.selfNotifications, formFieldDict, smtpTransport, constants.varFormat, function(err){ + if (form.selfNotifications && form.selfNotifications.enabled) { + if(form.selfNotifications.fromField){ + form.selfNotifications.fromEmails = formFieldDict[form.selfNotifications.fromField]; + } else { + form.selfNotifications.fromEmails = config.mailer.options.from; + } + + emailNotifications.send(form.selfNotifications, formFieldDict, smtpTransport, function(err){ if(err){ return callback({ message: 'Failure sending submission self-notification email' @@ -102,7 +106,7 @@ exports.createSubmission = function(req, res) { form.respondentNotifications.toEmails = formFieldDict[form.respondentNotifications.toField]; debugger; - emailNotifications.send(form.respondentNotifications, formFieldDict, smtpTransport, constants.varFormat, function(err){ + emailNotifications.send(form.respondentNotifications, formFieldDict, smtpTransport, function(err){ if(err){ return callback({ message: 'Failure sending submission respondent-notification email' @@ -196,13 +200,21 @@ exports.getVisitorData = function(req, res) { responses: "$responses", visits: "$visits", average_time: { - $divide : ["$total_time", "$responses"] + $cond: [ + { $eq: [ "$responses", 0 ] }, + 0, + { $divide: ["$total_time", "$responses"] } + ] }, conversion_rate: { $multiply: [ 100, { - $divide : ["$responses", "$visits"] + $cond: [ + { $eq: [ "$visits", 0 ] }, + 0, + { $divide: ["$responses", "$visits"] } + ] } ] } @@ -252,13 +264,21 @@ exports.getVisitorData = function(req, res) { responses: "$responses", visits: "$visits", average_time: { - $divide : ["$total_time", "$responses"] + $cond: [ + { $eq: [ "$responses", 0 ] }, + 0, + { $divide: ["$total_time", "$responses"] } + ] }, conversion_rate: { $multiply: [ 100, { - $divide : ["$responses", "$visits"] + $cond: [ + { $eq: [ "$visits", 0 ] }, + 0, + { $divide: ["$responses", "$visits"] } + ] } ] } @@ -499,7 +519,7 @@ exports.formByID = function(req, res, next, id) { } Form.findById(id) - .select('admin title language form_fields startPage endPage hideFooter isLive design analytics.gaCode respondentNotifications selfNotifications') + .select('admin title language form_fields startPage endPage showFooter isLive design analytics.gaCode respondentNotifications selfNotifications') .populate('admin') .exec(function(err, form) { if (err) { @@ -528,7 +548,7 @@ exports.formByIDFast = function(req, res, next, id) { } Form.findById(id) .lean() - .select('title language form_fields startPage endPage hideFooter isLive design analytics.gaCode selfNotifications respondentNotifications') + .select('title language form_fields startPage endPage showFooter isLive design analytics.gaCode selfNotifications respondentNotifications') .exec(function(err, form) { if (err) { return next(err); diff --git a/app/controllers/users/users.authentication.server.controller.js b/app/controllers/users/users.authentication.server.controller.js index 240f6412..852c20c7 100755 --- a/app/controllers/users/users.authentication.server.controller.js +++ b/app/controllers/users/users.authentication.server.controller.js @@ -126,7 +126,6 @@ exports.signup = function(req, res) { // Then save the temporary user nev.createTempUser(user, function (err, existingPersistentUser, newTempUser) { if (err) { - console.log(err); return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); diff --git a/app/controllers/users/users.password.server.controller.js b/app/controllers/users/users.password.server.controller.js index 99e480bf..fd66b6b1 100755 --- a/app/controllers/users/users.password.server.controller.js +++ b/app/controllers/users/users.password.server.controller.js @@ -113,7 +113,6 @@ exports.forgot = function(req, res) { } ], function(err, obfuscatedEmail) { if (err) { - console.log(err); return res.status(400).send({ message: 'Couldn\'t send reset password email due to internal server errors. Please contact support at team@tellform.com.' }); diff --git a/app/libs/constants.js b/app/libs/constants.js index 96b6610c..9e5d92e8 100644 --- a/app/libs/constants.js +++ b/app/libs/constants.js @@ -74,8 +74,5 @@ module.exports = { url: /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/, hexCode: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/, email: /^(([^<>()\[\]\\.,;:\s@']+(\.[^<>()\[\]\\.,;:\s@']+)*)|('.+'))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, - templateVariable: /(.|\n)*?<\/var>/g - }, - - varFormat: [']+)id=["\']{1}field:', '["\']{1}>([^<>]+)*?<\/var>'], + } }; \ No newline at end of file diff --git a/app/libs/send-email-notifications.js b/app/libs/send-email-notifications.js index 30af3aad..95a9ccbf 100644 --- a/app/libs/send-email-notifications.js +++ b/app/libs/send-email-notifications.js @@ -1,9 +1,12 @@ 'use strict'; +const jsdom = require("jsdom"); +var JSDOM = jsdom.JSDOM; module.exports = { - send: function(emailSettings, emailTemplateVars, smtpTransport, varFormat, cb){ - var parsedTemplate = this.parseTemplate(emailSettings.htmlTemplate, emailTemplateVars, varFormat); - var parsedSubject = this.parseTemplate(emailSettings.subject, emailTemplateVars, varFormat); + send: function(emailSettings, emailTemplateVars, smtpTransport, cb){ + var parsedTemplate = this.parseTemplate(emailSettings.htmlTemplate, emailTemplateVars, false); + var parsedSubject = this.parseTemplate(emailSettings.subject, emailTemplateVars, true); + var mailOptions = { replyTo: emailSettings.fromEmails, from: 'noreply@tellform.com', @@ -12,31 +15,41 @@ module.exports = { html: parsedTemplate }; - console.log('HERE'); - smtpTransport.sendMail(mailOptions, function(){ - console.log('THERE'); - cb(); + smtpTransport.sendMail(mailOptions, function(err){ + cb(err); }); }, - parseTemplate: function(emailTemplate, emailAttrs, varFormat){ - var resolvedTemplate = emailTemplate; - var that = this; - Object.keys(emailAttrs).forEach(function (key) { - resolvedTemplate = that.replaceTemplateVal(key, emailAttrs[key], resolvedTemplate, varFormat); - }); - return resolvedTemplate; - }, + parseTemplate: function(emailTemplate, emailTemplateVars, onlyText){ + var dom = new JSDOM(''+emailTemplate); - replaceTemplateVal: function(key, val, template, varFormat){ - return template.replace( new RegExp(varFormat[0] + key + varFormat[1], 'g'), val); + Object.keys(emailTemplateVars).forEach(function (key) { + var elem = dom.window.document.querySelector("span.placeholder-tag[data-id='" + key + "']"); + if(elem !== null){ + elem.outerHTML = emailTemplateVars[key]; + } + }); + + //Removed unused variables + //TODO: Currently querySelectorAll not working in JSDOM + /* + dom.window.document.querySelectorAll("span[data-id]").forEach(function(elem){ + if(elem !== null){ + elem.outerHTML = ''; + } + }) + */ + if(onlyText){ + return dom.window.document.documentElement.textContent; + } + return dom.serialize(); }, createFieldDict: function(form_fields){ var formFieldDict = {}; form_fields.forEach(function(field){ if(field.hasOwnProperty('globalId') && field.hasOwnProperty('fieldValue')){ - formFieldDict[field.globalId] = field.fieldValue; + formFieldDict[field.globalId+''] = field.fieldValue+''; } }); return formFieldDict; diff --git a/app/models/form.server.model.js b/app/models/form.server.model.js index be4e6b5c..c6fd922b 100644 --- a/app/models/form.server.model.js +++ b/app/models/form.server.model.js @@ -192,9 +192,9 @@ var FormSchema = new Schema({ } }, - hideFooter: { + showFooter: { type: Boolean, - default: false + default: true }, isLive: { @@ -264,6 +264,16 @@ function formFieldsAllHaveIds(form_fields){ return true; } +FormSchema.pre('save', function (next) { + if(this.form_fields && this.form_fields.length){ + this.form_fields = this.form_fields.filter(function(field){ + return !field.deletePreserved; + }); + } + next(); +}); + +/* FormSchema.pre('save', function (next) { var that = this; var _original; @@ -374,6 +384,7 @@ FormSchema.pre('save', function (next) { next(); }); }); +*/ FormSchema.index({created: 1}); diff --git a/app/tests/form_submission.model.test.js b/app/tests/form_submission.model.test.js index 262fbf04..b857e9a9 100644 --- a/app/tests/form_submission.model.test.js +++ b/app/tests/form_submission.model.test.js @@ -176,6 +176,7 @@ describe('FormSubmission Model Unit Tests:', function() { }); }); + /* describe('Test FormField and Submission Logic', function() { beforeEach(function(done){ @@ -245,6 +246,7 @@ describe('FormSubmission Model Unit Tests:', function() { }); }); }); + */ afterEach(function(done) { Form.remove().exec(function() { diff --git a/app/tests/libs/send-email-notifications.test.js b/app/tests/libs/send-email-notifications.test.js index 10f8d98f..9f9db698 100644 --- a/app/tests/libs/send-email-notifications.test.js +++ b/app/tests/libs/send-email-notifications.test.js @@ -3,9 +3,11 @@ /** * Module dependencies. */ -const emailNotifications = require('../../libs/send-email-notifications'), - constants = require('../../libs/constants'), - mockTransport = require("nodemailer").createTransport("Stub"), +const should = require('should'), + emailNotifications = require('../../libs/send-email-notifications'), + mockTransport = require('nodemailer').createTransport({ + jsonTransport: true + }), config = require('../../../config/config'); /** @@ -20,7 +22,7 @@ const validFormFields = [ const validFieldDict = { '56340745f59a6fc9e22028e9': 'John Smith', '5c9e22028e907634f45f59a6': 'https://johnsmith.me', - '56e90745f5934fc9e22028a6': 45 + '56e90745f5934fc9e22028a6': '45' }; const invalidFormFields = [ @@ -29,13 +31,11 @@ const invalidFormFields = [ {fieldType:'number', title:'Your Age'} ]; -const htmlTemplate = '

First Name \ -
Your Website \ -
Your Age

'; +const htmlTemplate = '

First Name'+ + '
Your Website'+ + '
Your Age

'; -const renderedTemplate = '

John Smith \ -
https://johnsmith.me \ -
45

'; +const renderedTemplate = '

John Smith
https://johnsmith.me
45

'; /** * Unit tests @@ -56,36 +56,24 @@ describe('Send Email Notification Unit Tests', function() { describe('Method parseTemplate', function(){ it('should properly render a template given a valid field dict', function() { - var actualRenderedTemplate = emailNotifications.parseTemplate(htmlTemplate, validFieldDict, constants.varFormat).replace((/ |\r\n|\n|\r|\t/gm),''); + var actualRenderedTemplate = emailNotifications.parseTemplate(htmlTemplate, validFieldDict, false).replace((/ |\r\n|\n|\r|\t/gm),''); actualRenderedTemplate.should.equal(renderedTemplate.replace((/ |\r\n|\n|\r|\t/gm),'')); }); }); - describe('Method replaceTemplateVal', function() { - it('should properly replace a template var in a valid template', function() { - var expectedHtml = '

John Smith \ -
Your Website \ -
Your Age

'; - - var actualRenderedTemplate = emailNotifications.replaceTemplateVal('56340745f59a6fc9e22028e9', validFieldDict['56340745f59a6fc9e22028e9'], htmlTemplate, constants.varFormat).replace((/ |\r\n|\n|\r|\t/gm),''); - actualRenderedTemplate.should.equal(expectedHtml.replace((/ |\r\n|\n|\r|\t/gm),'')); - }); - }); - describe('Method send', function() { this.timeout(10000); const emailSettings = { fromEmails: 'somewhere@somewhere.com', toEmails: 'there@there.com', - subject: 'Hello First Name!', + subject: 'Hello First Name!', htmlTemplate: htmlTemplate }; const emailTemplateVars = validFieldDict; - const varFormat = constants.varFormat; it('should properly replace a template var in a valid template', function(done) { - emailNotifications.send(emailSettings, emailTemplateVars, mockTransport, varFormat, function(err){ + emailNotifications.send(emailSettings, emailTemplateVars, mockTransport, function(err){ should.not.exist(err); done(); }); diff --git a/app/views/form.server.view.pug b/app/views/form.server.view.pug index fa807c5f..9dbad5b2 100644 --- a/app/views/form.server.view.pug +++ b/app/views/form.server.view.pug @@ -59,7 +59,6 @@ html(lang='en', xmlns='http://www.w3.org/1999/xhtml') script(type='text/javascript'). socketUrl = "!{socketUrl}" - script(src='/static/lib/jquery/dist/jquery.min.js', type='text/javascript') link(rel='stylesheet', href='/static/lib/font-awesome/css/font-awesome.min.css') link(rel='stylesheet', href='/static/lib/bootstrap/dist/css/bootstrap.min.css') diff --git a/app/views/index.server.view.pug b/app/views/index.server.view.pug index 0d0c17fc..1c08be19 100644 --- a/app/views/index.server.view.pug +++ b/app/views/index.server.view.pug @@ -3,9 +3,9 @@ extends layout.server.view.pug block content section.content(ui-view='', ng-cloak='') - + link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.4/quill.snow.min.css') + link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.4/quill.bubble.min.css') link(rel='stylesheet', href='/static/lib/jquery-ui/themes/flick/jquery-ui.min.css') - script(src='/static/lib/jquery/jquery.min.js') //Embedding The User Object script(type='text/javascript'). @@ -44,6 +44,10 @@ block content script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.8/angular-strap.min.js') + script(src='https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.4/quill.min.js') + script(src='https://cdnjs.cloudflare.com/ajax/libs/ng-quill/3.5.1/ng-quill.js') + script(src='https://unpkg.com/quill-placeholder-module@0.2.0/dist/placeholder-module.js') + //Application JavaScript Files each jsFile in jsFiles script(type='text/javascript', src=jsFile) diff --git a/bower.json b/bower.json index 4336c3ac..ae37555a 100755 --- a/bower.json +++ b/bower.json @@ -16,13 +16,11 @@ "angular-mocks": "~1.4.7", "angular-bootstrap": "~0.14.3", "angular-ui-utils": "~3.0.0", - "angular-ui-router": "~0.2.11", "ng-file-upload": "^12.0.4", "angular-raven": "~0.5.11", "angular-ui-date": "~0.0.11", "lodash": "~3.10.0", "angular-ui-sortable": "~0.13.4", - "angular-permission": "~1.1.1", "file-saver.js": "~1.20150507.2", "angular-bootstrap-colorpicker": "~3.0.19", "angular-scroll": "^1.0.0", @@ -41,21 +39,17 @@ "socket.io-client": "^1.7.2", "css-toggle-switch": "^4.0.2", "angular-strap": "^2.3.12", - "textAngular": "^1.5.16", "angular-ui-select": "^0.19.8", "angular-bootstrap-switch": "^0.5.2", - "jquery": "^3.2.1" + "jquery": "^3.2.1", + "ng-quill": "https://github.com/KillerCodeMonkey/ng-quill", + "angular-ui-router": "^1.0.11", + "angular-permission": "^5.3.2" }, "resolutions": { "angular-bootstrap": "^0.14.0", - "angular": "1.4.14", - "jspdf": "~1.0.178", - "angular-sanitize": "1.4.14", - "angular-ui-sortable": "^0.17.1", - "angular-ui-date": "~0.0.11", - "angular-input-stars-directive": "master", - "angular-ui-select": "^0.19.8", - "jquery": "^3.2.1" + "jquery": "^3.2.1", + "angular-ui-router": "^1.0.11" }, "overrides": { "BOWER-PACKAGE": { diff --git a/package-lock.json b/package-lock.json index ab46ade9..8516edc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/node": { + "version": "8.0.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.52.tgz", + "integrity": "sha512-wOU/VRodnI/4Chxuu6R6bcyN9aE3rztO0i8R76PZO7+DxTXWy60nseGN4ujspucmxrfj5mzgCYPXiXqrD6KC3Q==" + }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -304,6 +314,11 @@ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -3194,6 +3209,11 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "content-type-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==" + }, "convert-source-map": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", @@ -3545,6 +3565,19 @@ "parserlib": "0.2.5" } }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=" + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "requires": { + "cssom": "0.3.2" + } + }, "ctype": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", @@ -3639,8 +3672,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "degenerator": { "version": "1.0.4", @@ -3767,6 +3799,11 @@ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" }, + "domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.0.tgz", + "integrity": "sha512-WpwuBlZ2lQRFa4H/4w49deb9rJLot9KmqrKKjMc9qBl7CID+DdC2swoa34ccRl+anL2B6bLp6TjFdIdnzekMBQ==" + }, "domhandler": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", @@ -4160,8 +4197,7 @@ "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "etag": { "version": "1.7.0", @@ -4533,8 +4569,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "faye-websocket": { "version": "0.4.4", @@ -7062,6 +7097,14 @@ "core-util-is": "1.0.2" } }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "1.0.3" + } + }, "html-minifier": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.0.3.tgz", @@ -7893,6 +7936,78 @@ "integrity": "sha512-xYuhvQ7I9PDJIGBWev9xm0+SMSed3ZDBAmvVjbFR1ZRLAF+vlXcQu6cRI9uAlj81rzikElRVteehwV7DuX2ZmQ==", "dev": true }, + "jsdom": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.3.0.tgz", + "integrity": "sha512-aPZTDl4MplzQhx5bLztk6nzjbEslmO3Q3+z0WpCMutL1XJDhZIRzir6R1Y8S84LgeT/7jhQvgtUMkY6oPwvlUw==", + "requires": { + "abab": "1.0.4", + "acorn": "5.2.1", + "acorn-globals": "4.1.0", + "array-equal": "1.0.0", + "content-type-parser": "1.0.2", + "cssom": "0.3.2", + "cssstyle": "0.2.37", + "domexception": "1.0.0", + "escodegen": "1.9.0", + "html-encoding-sniffer": "1.0.2", + "nwmatcher": "1.4.3", + "parse5": "3.0.3", + "pn": "1.0.0", + "request": "2.83.0", + "request-promise-native": "1.0.5", + "sax": "1.2.4", + "symbol-tree": "3.2.2", + "tough-cookie": "2.3.3", + "webidl-conversions": "4.0.2", + "whatwg-encoding": "1.0.3", + "whatwg-url": "6.3.0", + "xml-name-validator": "2.0.1" + }, + "dependencies": { + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==" + }, + "acorn-globals": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz", + "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", + "requires": { + "acorn": "5.2.1" + } + }, + "escodegen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", + "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "requires": { + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.5.7" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + } + } + }, "jshint": { "version": "2.9.5", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", @@ -8502,7 +8617,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "1.1.2", "type-check": "0.3.2" @@ -8761,6 +8875,11 @@ "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "log-driver": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", @@ -9849,6 +9968,11 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, + "nwmatcher": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", + "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==" + }, "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", @@ -9916,7 +10040,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, "requires": { "deep-is": "0.1.3", "fast-levenshtein": "2.0.6", @@ -9929,8 +10052,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" } } }, @@ -10093,6 +10215,14 @@ "error-ex": "1.3.1" } }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "8.0.52" + } + }, "parsejson": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", @@ -10492,11 +10622,15 @@ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.3.tgz", "integrity": "sha1-ZGx3ARiZhwtqCQPnXpl+jlHadGE=" }, + "pn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.0.0.tgz", + "integrity": "sha1-HPWjCw2AbNGPiPxBprXUrWFbO6k=" + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "1.0.4", @@ -11286,6 +11420,24 @@ "throttleit": "1.0.0" } }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "4.17.4" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1", + "tough-cookie": "2.3.3" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11386,6 +11538,11 @@ "graceful-fs": "1.2.3" } }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "scandirectory": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/scandirectory/-/scandirectory-2.5.0.tgz", @@ -11931,6 +12088,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, "stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", @@ -12144,6 +12306,11 @@ "upper-case": "1.1.3" } }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" + }, "taskgroup": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/taskgroup/-/taskgroup-4.3.1.tgz", @@ -12289,6 +12456,21 @@ "punycode": "1.4.1" } }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + } + } + }, "transformers": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz", @@ -12364,7 +12546,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "1.1.2" } @@ -12723,6 +12904,36 @@ "typechecker": "2.1.0" } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "requires": { + "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + } + } + }, + "whatwg-url": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.3.0.tgz", + "integrity": "sha512-rM+hE5iYKGPAOu05mIdJR47pYSR2vDzfrTEFRc/S8D3L60yW8BuXmUJ7Kog7x/DrokFN7JNaHKadpzjouKRRAw==", + "requires": { + "lodash.sortby": "4.7.0", + "tr46": "1.0.1", + "webidl-conversions": "4.0.2" + } + }, "which": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", @@ -12887,6 +13098,11 @@ "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=" }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" + }, "xmlhttprequest-ssl": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", diff --git a/package.json b/package.json index 5f3ba4c4..1602d47e 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "helmet": "3.5.0", "i18n": "^0.8.3", "jit-grunt": "^0.9.1", + "jsdom": "^11.3.0", "lodash": "^4.17.4", "main-bower-files": "~2.9.0", "method-override": "~2.3.0", diff --git a/public/form_modules/forms/base/directives/on-enter-key.client.directive.js b/public/form_modules/forms/base/directives/on-enter-key.client.directive.js index eb4e5cfd..c90fd5ac 100644 --- a/public/form_modules/forms/base/directives/on-enter-key.client.directive.js +++ b/public/form_modules/forms/base/directives/on-enter-key.client.directive.js @@ -65,8 +65,6 @@ angular.module('view-form').directive('onEnterKey', ['$rootScope', function($roo var keyCode = event.which || event.keyCode; if(keyCode === 9 && event.shiftKey) { - - console.log('onTabAndShiftKey'); event.preventDefault(); $rootScope.$apply(function() { $rootScope.$eval($attrs.onTabAndShiftKey); diff --git a/public/form_modules/forms/base/directives/submit-form.client.directive.js b/public/form_modules/forms/base/directives/submit-form.client.directive.js index 4e9b2b1d..667b389e 100644 --- a/public/form_modules/forms/base/directives/submit-form.client.directive.js +++ b/public/form_modules/forms/base/directives/submit-form.client.directive.js @@ -15,18 +15,12 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun templateUrl: 'form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html', restrict: 'E', scope: { - myform:'=', - ispreview: '=' + myform:'=' }, controller: function($document, $window, $scope){ var FORM_ACTION_ID = 'submit_field'; $scope.forms = {}; - //Don't start timer if we are looking at a design preview - if($scope.ispreview){ - TimeCounter.restartClock(); - } - var form_fields_count = $scope.myform.visible_form_fields.filter(function(field){ return field.fieldType !== 'statement'; }).length; @@ -35,8 +29,7 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun $scope.myform.visible_form_fields = $scope.myform.form_fields.filter(function(field){ return !field.deletePreserved; }); - console.log($scope.myform.visible_form_fields); - }) + }); $scope.updateFormValidity = function(){ $timeout(function(){ @@ -320,12 +313,11 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun setTimeout(function () { $scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form) - .success(function (data, status) { + .then(function (data, status) { $scope.myform.submitted = true; $scope.loading = false; SendVisitorData.send(form, getActiveField(), _timeElapsed); - }) - .error(function (error) { + }, function (error) { $scope.loading = false; console.error(error); $scope.error = error.message; diff --git a/public/form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html b/public/form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html index 4a85cb36..8b065343 100755 --- a/public/form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html +++ b/public/form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html @@ -72,7 +72,7 @@ -