From a15a7fbbd9073a6a5b8a72fb5eb9cc35cb62d233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mahieu?= Date: Fri, 8 Jan 2016 10:32:20 +0100 Subject: [PATCH] refactor(umd): Better support of UMD * Remove manual wrapper by `grunt-umd` which produces a clean UMD wrapper - dependencies are not required at the start of the script, not in middle, deferred, `angular.run()`. - Fix #1016 - Fix #1013 - Fix #892 * Remove reference to `window` when using rangy. The wrapper exposes `rangy` in the closure. * Fix #853 : `rangy/lib/rangy-selectionsaverestore` exports `rangy` itself. There is no need to copy it in `rangy.saveSelection`, in fact it extends it! * Modify the `main` in package.json for pointing to non-minified, UMD ready file, debugging will be easier. --- Gruntfile.js | 47 ++++++++++++++++++++++++++++++++++------------- package.json | 3 ++- src/DOM.js | 5 ++--- src/main.js | 39 ++++++--------------------------------- src/taBind.js | 12 ++++++------ 5 files changed, 50 insertions(+), 56 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 17d825e5..c68931d8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,11 +14,12 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-bump'); grunt.loadNpmTasks('grunt-git'); grunt.loadNpmTasks('grunt-shell'); + grunt.loadNpmTasks('grunt-umd'); - grunt.registerTask('compile', ['concat', 'copy:setupFiles', 'jshint', 'uglify']); + grunt.registerTask('compile', ['concat', 'umd', 'copy:setupFiles', 'jshint', 'uglify']); grunt.registerTask('default', ['compile', 'test']); grunt.registerTask('test', ['clean:coverage', 'jshint', 'karma', 'coverage']); - grunt.registerTask('travis-test', ['concat', 'copy:setupFiles', 'jshint', 'karma', 'coverage', 'coveralls']); + grunt.registerTask('travis-test', ['concat', 'umd', 'copy:setupFiles', 'jshint', 'karma', 'coverage', 'coveralls']); grunt.registerTask('release', ['bump-only','compile', 'demo_pages', 'changelog','gitcommit','bump-commit', 'shell:publish']); grunt.registerTask('release:patch', ['bump-only:patch','compile','changelog','gitcommit','bump-commit', 'shell:publish']); @@ -131,28 +132,48 @@ module.exports = function (grunt) { } }, concat: { - options: { - banner: "/*\n@license textAngular\nAuthor : Austin Anderson\nLicense : 2013 MIT\nVersion <%- pkg.version %>\n\nSee README.md or https://github.com/fraywing/textAngular/wiki for requirements and use.\n*/\n\n/*\nCommonjs package manager support (eg componentjs).\n*/\n\n/* istanbul ignore next: */\n'undefined'!=typeof module&&'undefined'!=typeof exports&&module.exports===exports&&(module.exports='textAngular');\n\n(function(){ // encapsulate all variables so they don't become global vars\n\"use strict\";", - footer: "})();" - }, - dist: { - files:{ - 'dist/textAngular.js': ['src/globals.js','src/factories.js','src/DOM.js','src/validators.js','src/taBind.js','src/main.js'], + dist: { + options: { + banner: "/*\n@license textAngular\nAuthor : Austin Anderson\nLicense : 2013 MIT\nVersion <%- pkg.version %>\n\nSee README.md or https://github.com/fraywing/textAngular/wiki for requirements and use.\n*/\n\n/*\nCommonjs package manager support (eg componentjs).\n*/\n\n\n\"use strict\";" + }, + files:{ + 'dist/textAngular.js': ['src/globals.js','src/factories.js','src/DOM.js','src/validators.js','src/taBind.js','src/main.js'], + } + }, + umd: { + files: { + 'dist/textAngular.umd.js': ['dist/textAngularSetup.js', 'dist/textAngular.js'] + } + } + }, + umd: { + all: { + options: { + src: 'dist/textAngular.umd.js', + dest: 'dist/textAngular.umd.js', + objectToExport: 'textAngular.name', + globalAlias: 'textAngular', + amdModuleId: 'textAngular', + deps: { + 'default': ['rangy'], + cjs: ['rangy', {'rangy/lib/rangy-selectionsaverestore': ''}], + amd: ['rangy', {'rangy/lib/rangy-selectionsaverestore': ''}] } - }, - }, + } + } + }, uglify: { options: { mangle: true, compress: {}, - wrap: true, + wrap: false, preserveComments: 'some' }, my_target: { files: { 'dist/textAngular-rangy.min.js': ['bower_components/rangy/rangy-core.js', 'bower_components/rangy/rangy-selectionsaverestore.js'], 'dist/textAngular-sanitize.min.js': ['src/textAngular-sanitize.js'], - 'dist/textAngular.min.js': ['dist/textAngularSetup.js','dist/textAngular.js'] + 'dist/textAngular.min.js': ['dist/textAngular.umd.js'] } } }, diff --git a/package.json b/package.json index fb4e5779..1b3ac65b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ ], "license": "MIT", "homepage": "http://textangular.com", - "main": "./dist/textAngular.min.js", + "main": "./dist/textAngular.umd.js", "dependencies": { "rangy": "^1.3.0" }, @@ -45,6 +45,7 @@ "grunt-karma": "^0.6.2", "grunt-karma-coveralls": "^2.5.0", "grunt-shell": "^1.1.1", + "grunt-umd": "^2.3.5", "karma": "^0.10.10", "karma-chrome-launcher": "~0.1.2", "karma-coverage": "~0.2.0", diff --git a/src/DOM.js b/src/DOM.js index baa13920..89a524ed 100644 --- a/src/DOM.js +++ b/src/DOM.js @@ -229,12 +229,11 @@ angular.module('textAngular.DOM', ['textAngular.factories']) }catch(e){} }; }; -}]).service('taSelection', ['$window', '$document', 'taDOM', +}]).service('taSelection', ['$document', 'taDOM', /* istanbul ignore next: all browser specifics and PhantomJS dosen't seem to support half of it */ -function($window, $document, taDOM){ +function($document, taDOM){ // need to dereference the document else the calls don't work correctly var _document = $document[0]; - var rangy = $window.rangy; var brException = function (element, offset) { /* check if selection is a BR element at the beginning of a container. If so, get * the parentNode instead. diff --git a/src/main.js b/src/main.js index 60f06f89..34340db6 100644 --- a/src/main.js +++ b/src/main.js @@ -7,38 +7,11 @@ textAngular.config([function(){ angular.forEach(taTools, function(value, key){ delete taTools[key]; }); }]); -textAngular.run([function(){ - /* istanbul ignore next: not sure how to test this */ - // Require Rangy and rangy savedSelection module. - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(function(require) { - window.rangy = require('rangy'); - window.rangy.saveSelection = require('rangy/lib/rangy-selectionsaverestore'); - }); - } else if (typeof require ==='function' && typeof module !== 'undefined' && typeof exports === 'object') { - // Node/CommonJS style - window.rangy = require('rangy'); - window.rangy.saveSelection = require('rangy/lib/rangy-selectionsaverestore'); - } else { - // Ensure that rangy and rangy.saveSelection exists on the window (global scope). - // TODO: Refactor so that the global scope is no longer used. - if(!window.rangy){ - throw("rangy-core.js and rangy-selectionsaverestore.js are required for textAngular to work correctly, rangy-core is not yet loaded."); - }else{ - window.rangy.init(); - if(!window.rangy.saveSelection){ - throw("rangy-selectionsaverestore.js is required for textAngular to work correctly."); - } - } - } -}]); - textAngular.directive("textAngular", [ '$compile', '$timeout', 'taOptions', 'taSelection', 'taExecCommand', - 'textAngularManager', '$window', '$document', '$animate', '$log', '$q', '$parse', + 'textAngularManager', '$document', '$animate', '$log', '$q', '$parse', function($compile, $timeout, taOptions, taSelection, taExecCommand, - textAngularManager, $window, $document, $animate, $log, $q, $parse){ + textAngularManager, $document, $animate, $log, $q, $parse){ return { require: '?ngModel', scope: {}, @@ -350,9 +323,9 @@ textAngular.directive("textAngular", [ scope.startAction = function(){ scope._actionRunning = true; // if rangy library is loaded return a function to reload the current selection - _savedSelection = $window.rangy.saveSelection(); + _savedSelection = rangy.saveSelection(); return function(){ - if(_savedSelection) $window.rangy.restoreSelection(_savedSelection); + if(_savedSelection) rangy.restoreSelection(_savedSelection); }; }; scope.endAction = function(){ @@ -363,8 +336,8 @@ textAngular.directive("textAngular", [ }else{ scope.displayElements.text[0].focus(); } - // $window.rangy.restoreSelection(_savedSelection); - $window.rangy.removeMarkers(_savedSelection); + // rangy.restoreSelection(_savedSelection); + rangy.removeMarkers(_savedSelection); } _savedSelection = false; scope.updateSelectedStyles(); diff --git a/src/taBind.js b/src/taBind.js index b7f78864..20ef1016 100644 --- a/src/taBind.js +++ b/src/taBind.js @@ -41,11 +41,11 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM' }; }]) .directive('taBind', [ - 'taSanitize', '$timeout', '$window', '$document', 'taFixChrome', 'taBrowserTag', + 'taSanitize', '$timeout', '$document', 'taFixChrome', 'taBrowserTag', 'taSelection', 'taSelectableElements', 'taApplyCustomRenderers', 'taOptions', '_taBlankTest', '$parse', 'taDOM', 'textAngularManager', function( - taSanitize, $timeout, $window, $document, taFixChrome, taBrowserTag, + taSanitize, $timeout, $document, taFixChrome, taBrowserTag, taSelection, taSelectableElements, taApplyCustomRenderers, taOptions, _taBlankTest, $parse, taDOM, textAngularManager){ // Uses for this are textarea or input with ng-model and ta-bind='text' @@ -685,13 +685,13 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM' e.preventDefault(); return false; } else {// Everything else - empty editdiv and allow browser to paste content into it, then cleanup - var _savedSelection = $window.rangy.saveSelection(), + var _savedSelection = rangy.saveSelection(), _tempDiv = angular.element('
'); $document.find('body').append(_tempDiv); _tempDiv[0].focus(); $timeout(function(){ // restore selection - $window.rangy.restoreSelection(_savedSelection); + rangy.restoreSelection(_savedSelection); processpaste(_tempDiv[0].innerHTML); element[0].focus(); _tempDiv.remove(); @@ -822,11 +822,11 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM' taSelection.setSelectionToElementStart(element.children()[0]); }else if(val.substring(0, 1) !== '<' && attrs.taDefaultWrap !== ''){ /* we no longer do this, since there can be comments here and white space - var _savedSelection = $window.rangy.saveSelection(); + var _savedSelection = rangy.saveSelection(); val = _compileHtml(); val = "<" + attrs.taDefaultWrap + ">" + val + ""; _setInnerHTML(val); - $window.rangy.restoreSelection(_savedSelection); + rangy.restoreSelection(_savedSelection); */ } var triggerUndo = _lastKey !== event.keyCode && UNDO_TRIGGER_KEYS.test(event.keyCode);