diff --git a/.gitignore b/.gitignore index 921f98181..808900fad 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,11 @@ .settings/ .sass-cache/ .project +grapes.sublime-project +grapes.sublime-workspace private/ libs/ +vendor/ node_modules/ +bower_components/ diff --git a/Gruntfile.js b/Gruntfile.js index 3f4664067..fdffd71ea 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,17 +1,18 @@ -module.exports = function(grunt) { - - var appPath = 'src', - buildPath = 'dist', - configPath = 'config/require-config.js'; - +module.exports = function(grunt) { + + var appPath = 'src', + buildPath = 'dist', + configPath = 'config/require-config.js'; + grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-sass'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-requirejs'); grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-bowercopy'); grunt.loadNpmTasks('grunt-mocha'); - + grunt.initConfig({ appDir: appPath, builtDir: buildPath, @@ -27,20 +28,20 @@ module.exports = function(grunt) { removeCombined: true, findNestedDependencies: true, keepBuildDir: true, - inlineText: true, + inlineText: true, optimize: 'none' //paths: { "jquery": "empty:" }, //try to exclude } } }, - + jshint: { all: [ 'Gruntfile.js', '<%= appDir %>/**/*.js', ] }, - + uglify: { options: { banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> */' @@ -51,7 +52,7 @@ module.exports = function(grunt) { } } }, - + sass: { dist: { files: [{ @@ -63,17 +64,17 @@ module.exports = function(grunt) { }] } }, - + mocha: { test: { src: ['test/index.html'], options: { log: true, }, }, }, - + connect: { /* - app: { + dist: { options: { port: 8001, open: { @@ -91,7 +92,34 @@ module.exports = function(grunt) { } } }, - + + bowercopy: { + options: { + srcPrefix: 'bower_components' + }, + scripts: { + options: { + destPrefix: 'vendor' + }, + files: { + 'jquery/jquery.js' : 'jquery/dist/jquery.min.js', + 'jquery-ui/jquery-ui-core.js' : 'jquery.ui/ui/core.js', + 'jquery-ui/jquery-ui-mouse.js' : 'jquery.ui/ui/mouse.js', + 'jquery-ui/jquery-ui-widget.js' : 'jquery.ui/ui/widget.js', + 'jquery-ui/jquery-ui.js' : 'jquery.ui/ui/resizable.js', + 'underscore/underscore.js' : 'underscore/underscore-min.js', + 'backbone/backbone.js' : 'backbone/backbone-min.js', + 'backbone-undo/backbone-undo.js' : 'Backbone.Undo/Backbone.Undo.js', + 'keymaster/keymaster.js' : 'keymaster/keymaster.js', + 'require/require.js' : 'requirejs/require.js', + 'require-text/text.js' : 'requirejs-text/text.js', + 'spectrum/spectrum.js' : 'spectrum/spectrum.js', + 'codemirror' : 'codemirror', + 'codemirror-formatting' : 'codemirror-formatting/formatting.js', + }, + } + }, + watch: { script: { files: [ '<%= appDir %>/**/*.js' ], @@ -102,17 +130,17 @@ module.exports = function(grunt) { tasks: ['sass'] }, test: { - files: [ 'test/specs/**/*.js' ], + files: ['test/specs/**/*.js'], tasks: ['mocha'], options: { livereload: true }, //default port 35729 } } - + }); - + /** * Need to copy require configs cause r.js will try to load them from the path indicated inside - * main.js file. This is the only way I have found to do it and only for the pleasure of using separate config + * main.js file. This is the only way I have found to do it and only for the pleasure of using separate config * requirejs file. * */ grunt.registerTask('before-requirejs', function() { @@ -121,17 +149,19 @@ module.exports = function(grunt) { grunt.file.mkdir(buildPath); grunt.file.copy(appPath + '/' + configPath, buildPath + '/' + appPath + '/' + configPath); }); - + grunt.registerTask('after-requirejs', function() { //grunt.file.copy(buildPath + '/main.js', buildPath + '/main.min.js'); }); - + + grunt.registerTask('bower', ['bowercopy']); + grunt.registerTask('dev', ['connect', 'watch']); - + grunt.registerTask('test', ['mocha']); - + grunt.registerTask('deploy', ['jshint', 'before-requirejs', 'requirejs', 'after-requirejs', 'uglify']); - + grunt.registerTask('default', ['dev']); - + }; \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100644 index 000000000..a38c3e332 --- /dev/null +++ b/bower.json @@ -0,0 +1,40 @@ +{ + "name": "grapes", + "description": "Open source web template editor", + "version": "0.0.5", + "author": "Artur Arseniev", + "main": [ + "dist/grapes.min.js" + ], + "keywords": [ + "grapes", + "wte", + "web template editor", + "site builder", + "newsletter builder", + "wysiwyg", + "template", + "editor" + ], + "license": "BSD-3-Clause", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "backbone": "~1.2.3", + "Backbone.Undo": "~0.2.5", + "jquery": "~2.2.0", + "jquery.ui": "~1.11.4", + "keymaster": "~1.6.3", + "requirejs": "~2.1.22", + "requirejs-text": "~2.0.14", + "spectrum": "~1.8.0", + "underscore": "~1.8.3", + "codemirror": "~5.10.0", + "codemirror-formatting": "*" + } +} diff --git a/index.html b/index.html index a99a989a7..bddc8b68f 100755 --- a/index.html +++ b/index.html @@ -6,10 +6,11 @@ - + +
- + diff --git a/package.json b/package.json index b1ac1b42f..04547b451 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,45 @@ { - "name": "grapes.js", + "name": "grapes", "description": "Open source web template editor", "version": "0.0.5", + "author": "Artur Arseniev", "private": true, "dependencies": { - "backbone": "1.2.0", - "backbone-undo": "0.2", + "backbone": "^1.2.3", + "backbone-undo": "^0.2.5", + "bootstrap-wysiwyg": "^1.0.4", + "codemirror": "^5.10.0", + "jquery": "^2.2.0", + "jquery-ui": "^1.10.5", "keymaster": "^1.6.2", - "requirejs": "latest", - "spectrum-colorpicker": "1.7.1" + "requirejs": "^2.1.22", + "spectrum-colorpicker": "^1.8.0", + "text": "git://github.com/requirejs/text", + "underscore": "^1.8.3" }, "devDependencies": { - "chai": "latest", - "grunt": "latest", + "chai": "^3.4.1", + "grunt": "^0.4.5", + "grunt-bowercopy": "^1.2.4", "grunt-contrib-connect": "^0.11.2", - "grunt-contrib-jshint": "latest", - "grunt-contrib-requirejs": "latest", + "grunt-contrib-jshint": "^0.12.0", + "grunt-contrib-requirejs": "^0.4.4", "grunt-contrib-sass": "^0.9.2", - "grunt-contrib-testem": "^0.5.16", "grunt-contrib-uglify": "^0.11.0", - "grunt-contrib-watch": "latest", - "grunt-mocha": "^0.4.15", - "grunt-testem": "^0.5.5", - "mocha": "latest" + "grunt-contrib-watch": "^0.6.1", + "grunt-mocha": "^0.4.15" }, "license": "BSD-3-Clause", + "keywords": [ + "grapes", + "wte", + "web template editor", + "site builder", + "newsletter builder", + "wysiwyg", + "template", + "editor" + ], "scripts": { "grunt": "node_modules/.bin/grunt" } diff --git a/src/asset_manager/view/AssetImageView.js b/src/asset_manager/view/AssetImageView.js index a6f1c4e5d..a76e5d7ce 100644 --- a/src/asset_manager/view/AssetImageView.js +++ b/src/asset_manager/view/AssetImageView.js @@ -1,38 +1,39 @@ -define(['./AssetView','text!./../template/assetImage.html'], +define(['./AssetView','text!./../template/assetImage.html'], function (AssetView, assetTemplate) { - /** + /** * @class AssetImageView * */ return AssetView.extend({ - + events:{ - 'click' : 'selected', + 'click' : 'selected', 'dblclick' : 'chosen', }, - + template: _.template(assetTemplate), - + initialize: function(o) { AssetView.prototype.initialize.apply(this, arguments); this.className += ' ' + this.pfx + 'asset-image'; this.events['click #' + this.pfx + 'close'] = 'removeItem'; + this.delegateEvents(); }, - + /** * Trigger when asset is been selected - * + * * @return void * */ selected: function(){ this.model.collection.trigger('deselectAll'); this.$el.addClass(this.pfx + 'highlight'); - + this.updateTarget(this.model.get('src')); }, - + /** * Trigger when asset is been chosen (double clicked) - * + * * @return void * */ chosen: function(){ @@ -42,11 +43,11 @@ define(['./AssetView','text!./../template/assetImage.html'], f(this.model); } }, - + /** * Update target if exists * @param {String} v Value - * + * * @return void * */ updateTarget: function(v){ @@ -58,27 +59,27 @@ define(['./AssetView','text!./../template/assetImage.html'], target.set('src', v ); } }, - + /** * Remove asset from collection - * + * * @return void * */ removeItem: function(e){ e.stopPropagation(); this.model.collection.remove(this.model); }, - + render : function(){ var name = this.model.get('name'), - dim = this.model.get('width') && this.model.get('height') ? + dim = this.model.get('width') && this.model.get('height') ? this.model.get('width')+' x '+this.model.get('height') : ''; name = name ? name : this.model.get('src').split("/").pop(); name = name && name.length > 30 ? name.substring(0, 30)+'...' : name; dim = dim ? dim + (this.model.get('unitDim') ? this.model.get('unitDim') : ' px' ) : ''; this.$el.html( this.template({ - name: name, - src: this.model.get('src'), + name: name, + src: this.model.get('src'), dim: dim, pfx: this.pfx })); diff --git a/src/asset_manager/view/FileUploader.js b/src/asset_manager/view/FileUploader.js index 667a009b3..d0d3a1c31 100644 --- a/src/asset_manager/view/FileUploader.js +++ b/src/asset_manager/view/FileUploader.js @@ -1,15 +1,15 @@ -define(['backbone', 'text!./../template/fileUploader.html'], +define(['backbone', 'text!./../template/fileUploader.html'], function (Backbone, fileUploaderTemplate) { - /** + /** * @class FileUploader * */ return Backbone.View.extend({ - + template: _.template(fileUploaderTemplate), - + events: {}, - + initialize: function(o) { this.options = o || {}; this.config = o.config || {}; @@ -18,12 +18,13 @@ define(['backbone', 'text!./../template/fileUploader.html'], this.uploadId = this.pfx + 'uploadFile'; this.disabled = this.config.disableUpload; this.events['change #' + this.uploadId] = 'uploadFile'; + this.delegateEvents(); }, - + /** * Upload files * @param {Object} e Event - * + * * @return void * */ uploadFile : function(e){ @@ -33,10 +34,10 @@ define(['backbone', 'text!./../template/fileUploader.html'], formData.append('files[]', files[i]); } var target = this.target; - $.ajax({ + $.ajax({ url : this.config.urlUpload, //this.config.urlUpload - type : 'POST', - data : formData, + type : 'POST', + data : formData, beforeSend : this.config.beforeSend, complete : this.config.onComplete, xhrFields : { @@ -49,17 +50,17 @@ define(['backbone', 'text!./../template/fileUploader.html'], //progress.value = 100; } }, - cache: false, contentType: false, processData: false + cache: false, contentType: false, processData: false }).done(function(data){ - target.add(data.data); + target.add(data.data); }).always(function(){ //turnOff loading }); }, - + /** * Make input file droppable - * + * * @return void * */ initDrop: function(){ @@ -68,27 +69,27 @@ define(['backbone', 'text!./../template/fileUploader.html'], this.uploadForm = this.$el.find('form').get(0); if( 'draggable' in this.uploadForm ){ var uploadFile = this.uploadFile; - this.uploadForm.ondragover = function(){ - this.className = that.pfx + 'hover'; - return false; + this.uploadForm.ondragover = function(){ + this.className = that.pfx + 'hover'; + return false; }; - this.uploadForm.ondragleave = function(){ - this.className = ''; - return false; + this.uploadForm.ondragleave = function(){ + this.className = ''; + return false; }; this.uploadForm.ondrop = function(e){ - this.className = ''; + this.className = ''; e.preventDefault(); that.uploadFile(e); - return; + return; }; } } }, - + render : function(){ this.$el.html( this.template({ - title : this.config.uploadText, + title : this.config.uploadText, uploadId : this.uploadId, disabled : this.disabled, pfx : this.pfx @@ -97,6 +98,6 @@ define(['backbone', 'text!./../template/fileUploader.html'], this.$el.attr('class', this.pfx + 'file-uploader'); return this; }, - + }); }); diff --git a/src/code_manager/model/CodeMirrorEditor.js b/src/code_manager/model/CodeMirrorEditor.js index 47705b408..cd8201bbb 100644 --- a/src/code_manager/model/CodeMirrorEditor.js +++ b/src/code_manager/model/CodeMirrorEditor.js @@ -1,16 +1,15 @@ define(['backbone', - 'text!../../../libs/codemirror/lib/codemirror.css', - '../../../libs/codemirror/lib/codemirror', - '../../../libs/codemirror/mode/htmlmixed/htmlmixed', - '../../../libs/codemirror/mode/css/css', - '../../../libs/codemirror/lib/util/formatting' + 'codemirror/lib/codemirror', + 'codemirror/mode/htmlmixed/htmlmixed', + 'codemirror/mode/css/css', + 'formatting' ], - function(Backbone, CodeMirrorStyle, CodeMirror, htmlMode, cssMode, formatting ) { - /** + function(Backbone, CodeMirror, htmlMode, cssMode, formatting) { + /** * @class CodeViewer * */ return Backbone.Model.extend({ - + defaults: { input : '', label : '', @@ -19,13 +18,13 @@ define(['backbone', readOnly : true, lineNumbers : true, }, - + /** @inheritdoc */ getId : function() { - return 'CodeMirror'; + return 'CodeMirror'; }, - + /** @inheritdoc */ init: function(el) { @@ -36,10 +35,10 @@ define(['backbone', mode : this.get('codeName'), theme : this.get('theme'), }); - + return this; }, - + /** @inheritdoc */ setContent : function(v) { @@ -52,6 +51,6 @@ define(['backbone', CodeMirror.commands.goDocStart(this.editor); } }, - + }); }); \ No newline at end of file diff --git a/src/commands/view/ExportTemplate.js b/src/commands/view/ExportTemplate.js index 6f4494736..1da11c0cf 100644 --- a/src/commands/view/ExportTemplate.js +++ b/src/commands/view/ExportTemplate.js @@ -1,9 +1,9 @@ define(function() { - /** + /** * @class ExportTemplate * */ return { - + run: function(em, sender){ this.sender = sender; this.components = em.get('Canvas').getWrapper().get('components'); @@ -11,63 +11,63 @@ define(function() { this.cm = em.get('CodeManager') || null; this.enable(); }, - + /** * Build editor * @param {String} codeName * @param {String} theme * @param {String} label - * + * * @return {Object} Editor * */ buildEditor: function(codeName, theme, label) { if(!this.codeMirror) this.codeMirror = this.cm.getEditor('CodeMirror'); - + var $input = $('