From fa904a49b78ba28940c2a30b153c5818b6f85d90 Mon Sep 17 00:00:00 2001 From: Dean Sofer Date: Mon, 3 Aug 2015 17:09:37 -0700 Subject: [PATCH 1/3] Initial version of blurring behavior --- bower.json | 2 +- dist/mention.js | 45 +++++++++++++++++++++++++++++++++++++++--- dist/mention.min.js | 2 +- package.json | 2 +- src/mention.es6.js | 48 +++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 89 insertions(+), 10 deletions(-) diff --git a/bower.json b/bower.json index c2c297f..3ba4cc4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-ui-mention", - "version": "0.0.4", + "version": "0.0.5", "homepage": "https://github.com/angular-ui/ui-mention", "authors": [ "AngularUI Team" diff --git a/dist/mention.js b/dist/mention.js index 19329f2..98fe7b5 100644 --- a/dist/mention.js +++ b/dist/mention.js @@ -2,7 +2,7 @@ var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); -angular.module('ui.mention', []).directive('uiMention', function ($q, $timeout) { +angular.module('ui.mention', []).directive('uiMention', function ($q, $timeout, $document) { return { require: ['ngModel', 'uiMention'], controllerAs: '$mention', @@ -173,8 +173,6 @@ angular.module('ui.mention', []).directive('uiMention', function ($q, $timeout) this.select = function () { var choice = arguments.length <= 0 || arguments[0] === undefined ? this.activeChoice : arguments[0]; - if (!this.searching) return; - // Add the mention this.mentions.push(choice); @@ -310,6 +308,47 @@ angular.module('ui.mention', []).directive('uiMention', function ($q, $timeout) $scope.$apply(); }); + // Fires before blur + var clicking = false; + this.onMousedown = function (event) { + if (event.target !== $element[0]) { + clicking = true; + $document.off('mousedown', this.onMousedown); + } + }; + + this.onMouseup = function (event) { + var _this4 = this; + + if (event.target !== $element[0]) $document.off('mouseup', this.onMouseup); + + if (!clicking) return; + + // Let ngClick fire first + $scope.$evalAsync(function () { + _this4.cancel(); + }); + }; + + $element.on('focus', function (event) { + $document.on('mousedown', _this2.onMousedown.bind(_this2)); + $document.on('mouseup', _this2.onMouseup.bind(_this2)); + }); + + $element.on('blur', function (event) { + if (clicking) { + return; + } else { + $document.off('mouseup', _this2.onMouseup); + $document.off('mousedown', _this2.onMousedown); + } + + if (!_this2.searching) return; + + _this2.cancel(); + $scope.$apply(); + }); + // Autogrow is mandatory beacuse the textarea scrolls away from highlights $element.on('input', this.autogrow); // Initialize autogrow height diff --git a/dist/mention.min.js b/dist/mention.min.js index 9eddf13..09285d6 100644 --- a/dist/mention.min.js +++ b/dist/mention.min.js @@ -1 +1 @@ -"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[],_n=!0,_d=!1,_e=void 0;try{for(var _s,_i=arr[Symbol.iterator]();!(_n=(_s=_i.next()).done)&&(_arr.push(_s.value),!i||_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{!_n&&_i["return"]&&_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr))return arr;if(Symbol.iterator in Object(arr))return sliceIterator(arr,i);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();angular.module("ui.mention",[]).directive("uiMention",function($q,$timeout){return{require:["ngModel","uiMention"],controllerAs:"$mention",link:function($scope,$element,$attrs,_ref){var _ref2=_slicedToArray(_ref,2),ngModel=_ref2[0],uiMention=_ref2[1];uiMention.init(ngModel)},controller:function($element,$scope,$attrs){var _this2=this;this.pattern=this.pattern||/(?:\s+|^)@(\w+(?: \w+)?)$/,this.$element=$element,this.choices=[],this.mentions=[];var ngModel;this.init=function(model){var _this=this;$attrs.ngTrim="false",ngModel=model,ngModel.$parsers.push(function(value){return _this.mentions=_this.mentions.filter(function(mention){return~value.indexOf(_this.label(mention))?value=value.replace(_this.label(mention),_this.encode(mention)):void 0}),_this.render(value),value}),ngModel.$formatters.push(function(){var value=arguments.length<=0||void 0===arguments[0]?"":arguments[0];return value=value.toString(),_this.mentions=_this.mentions.filter(function(mention){return~value.indexOf(_this.encode(mention))?(value=value.replace(_this.encode(mention),_this.label(mention)),!0):!1}),value}),ngModel.$render=function(){$element.val(ngModel.$viewValue||""),_this.render()}},this.render=function(){var html=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return html=(html||"").toString(),_this2.mentions.forEach(function(mention){html=html.replace(_this2.encode(mention),_this2.highlight(mention))}),$element.next().html(html),html},this.highlight=function(choice){return""+this.label(choice)+""},this.decode=function(){var value=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return value?value.replace(/@\[([\s\w]+):[0-9a-z-]+\]/gi,"$1"):""},this.label=function(choice){return choice.first+" "+choice.last},this.encode=function(choice){return"@["+this.label(choice)+":"+choice.id+"]"},this.replace=function(mention){var search=arguments.length<=1||void 0===arguments[1]?this.searching:arguments[1],text=arguments.length<=2||void 0===arguments[2]?ngModel.$viewValue:arguments[2];return text=text.substr(0,search.index+search[0].indexOf("@"))+this.label(mention)+" "+text.substr(search.index+search[0].length)},this.select=function(){var choice=arguments.length<=0||void 0===arguments[0]?this.activeChoice:arguments[0];this.searching&&(this.mentions.push(choice),ngModel.$setViewValue(this.replace(choice)),this.cancel(),ngModel.$render())},this.up=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index>0?this.choices[index-1]:this.choices[this.choices.length-1]},this.down=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index"+this.label(choice)+""},this.decode=function(){var value=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return value?value.replace(/@\[([\s\w]+):[0-9a-z-]+\]/gi,"$1"):""},this.label=function(choice){return choice.first+" "+choice.last},this.encode=function(choice){return"@["+this.label(choice)+":"+choice.id+"]"},this.replace=function(mention){var search=arguments.length<=1||void 0===arguments[1]?this.searching:arguments[1],text=arguments.length<=2||void 0===arguments[2]?ngModel.$viewValue:arguments[2];return text=text.substr(0,search.index+search[0].indexOf("@"))+this.label(mention)+" "+text.substr(search.index+search[0].length)},this.select=function(){var choice=arguments.length<=0||void 0===arguments[0]?this.activeChoice:arguments[0];this.mentions.push(choice),ngModel.$setViewValue(this.replace(choice)),this.cancel(),ngModel.$render()},this.up=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index>0?this.choices[index-1]:this.choices[this.choices.length-1]},this.down=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index { + this.cancel(); + }); + } + + $element.on('focus', event => { + $document.on('mousedown', this.onMousedown.bind(this)); + $document.on('mouseup', this.onMouseup.bind(this)); + }); + + $element.on('blur', event => { + if (clicking) { + return; + } else { + $document.off('mouseup', this.onMouseup); + $document.off('mousedown', this.onMousedown); + } + + if (!this.searching) + return; + + this.cancel(); + $scope.$apply(); + }); + // Autogrow is mandatory beacuse the textarea scrolls away from highlights $element.on('input', this.autogrow); // Initialize autogrow height From 1300c8b6871db1a7395f792dcf038a5ce6266016 Mon Sep 17 00:00:00 2001 From: Dean Sofer Date: Mon, 3 Aug 2015 17:20:13 -0700 Subject: [PATCH 2/3] Simplified implementation --- dist/mention.js | 37 ++++++++----------------------------- dist/mention.min.js | 2 +- src/mention.es6.js | 39 +++++++++------------------------------ 3 files changed, 18 insertions(+), 60 deletions(-) diff --git a/dist/mention.js b/dist/mention.js index 98fe7b5..5305e3f 100644 --- a/dist/mention.js +++ b/dist/mention.js @@ -308,45 +308,24 @@ angular.module('ui.mention', []).directive('uiMention', function ($q, $timeout, $scope.$apply(); }); - // Fires before blur - var clicking = false; - this.onMousedown = function (event) { - if (event.target !== $element[0]) { - clicking = true; - $document.off('mousedown', this.onMousedown); - } - }; - - this.onMouseup = function (event) { + this.onMouseup = (function (event) { var _this4 = this; - if (event.target !== $element[0]) $document.off('mouseup', this.onMouseup); + if (event.target == $element[0]) return; + console.log('blur'); + $document.off('mouseup', this.onMouseup); - if (!clicking) return; + if (!this.searching) return; // Let ngClick fire first $scope.$evalAsync(function () { _this4.cancel(); }); - }; + }).bind(this); $element.on('focus', function (event) { - $document.on('mousedown', _this2.onMousedown.bind(_this2)); - $document.on('mouseup', _this2.onMouseup.bind(_this2)); - }); - - $element.on('blur', function (event) { - if (clicking) { - return; - } else { - $document.off('mouseup', _this2.onMouseup); - $document.off('mousedown', _this2.onMousedown); - } - - if (!_this2.searching) return; - - _this2.cancel(); - $scope.$apply(); + console.log('focus'); + $document.on('mouseup', _this2.onMouseup); }); // Autogrow is mandatory beacuse the textarea scrolls away from highlights diff --git a/dist/mention.min.js b/dist/mention.min.js index 09285d6..36dcbff 100644 --- a/dist/mention.min.js +++ b/dist/mention.min.js @@ -1 +1 @@ -"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[],_n=!0,_d=!1,_e=void 0;try{for(var _s,_i=arr[Symbol.iterator]();!(_n=(_s=_i.next()).done)&&(_arr.push(_s.value),!i||_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{!_n&&_i["return"]&&_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr))return arr;if(Symbol.iterator in Object(arr))return sliceIterator(arr,i);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();angular.module("ui.mention",[]).directive("uiMention",function($q,$timeout,$document){return{require:["ngModel","uiMention"],controllerAs:"$mention",link:function($scope,$element,$attrs,_ref){var _ref2=_slicedToArray(_ref,2),ngModel=_ref2[0],uiMention=_ref2[1];uiMention.init(ngModel)},controller:function($element,$scope,$attrs){var _this2=this;this.pattern=this.pattern||/(?:\s+|^)@(\w+(?: \w+)?)$/,this.$element=$element,this.choices=[],this.mentions=[];var ngModel;this.init=function(model){var _this=this;$attrs.ngTrim="false",ngModel=model,ngModel.$parsers.push(function(value){return _this.mentions=_this.mentions.filter(function(mention){return~value.indexOf(_this.label(mention))?value=value.replace(_this.label(mention),_this.encode(mention)):void 0}),_this.render(value),value}),ngModel.$formatters.push(function(){var value=arguments.length<=0||void 0===arguments[0]?"":arguments[0];return value=value.toString(),_this.mentions=_this.mentions.filter(function(mention){return~value.indexOf(_this.encode(mention))?(value=value.replace(_this.encode(mention),_this.label(mention)),!0):!1}),value}),ngModel.$render=function(){$element.val(ngModel.$viewValue||""),_this.render()}},this.render=function(){var html=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return html=(html||"").toString(),_this2.mentions.forEach(function(mention){html=html.replace(_this2.encode(mention),_this2.highlight(mention))}),$element.next().html(html),html},this.highlight=function(choice){return""+this.label(choice)+""},this.decode=function(){var value=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return value?value.replace(/@\[([\s\w]+):[0-9a-z-]+\]/gi,"$1"):""},this.label=function(choice){return choice.first+" "+choice.last},this.encode=function(choice){return"@["+this.label(choice)+":"+choice.id+"]"},this.replace=function(mention){var search=arguments.length<=1||void 0===arguments[1]?this.searching:arguments[1],text=arguments.length<=2||void 0===arguments[2]?ngModel.$viewValue:arguments[2];return text=text.substr(0,search.index+search[0].indexOf("@"))+this.label(mention)+" "+text.substr(search.index+search[0].length)},this.select=function(){var choice=arguments.length<=0||void 0===arguments[0]?this.activeChoice:arguments[0];this.mentions.push(choice),ngModel.$setViewValue(this.replace(choice)),this.cancel(),ngModel.$render()},this.up=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index>0?this.choices[index-1]:this.choices[this.choices.length-1]},this.down=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index"+this.label(choice)+""},this.decode=function(){var value=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return value?value.replace(/@\[([\s\w]+):[0-9a-z-]+\]/gi,"$1"):""},this.label=function(choice){return choice.first+" "+choice.last},this.encode=function(choice){return"@["+this.label(choice)+":"+choice.id+"]"},this.replace=function(mention){var search=arguments.length<=1||void 0===arguments[1]?this.searching:arguments[1],text=arguments.length<=2||void 0===arguments[2]?ngModel.$viewValue:arguments[2];return text=text.substr(0,search.index+search[0].indexOf("@"))+this.label(mention)+" "+text.substr(search.index+search[0].length)},this.select=function(){var choice=arguments.length<=0||void 0===arguments[0]?this.activeChoice:arguments[0];this.mentions.push(choice),ngModel.$setViewValue(this.replace(choice)),this.cancel(),ngModel.$render()},this.up=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index>0?this.choices[index-1]:this.choices[this.choices.length-1]},this.down=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index { this.cancel(); }); - } + }).bind(this); $element.on('focus', event => { - $document.on('mousedown', this.onMousedown.bind(this)); - $document.on('mouseup', this.onMouseup.bind(this)); - }); - - $element.on('blur', event => { - if (clicking) { - return; - } else { - $document.off('mouseup', this.onMouseup); - $document.off('mousedown', this.onMousedown); - } - - if (!this.searching) - return; - - this.cancel(); - $scope.$apply(); + console.log('focus') + $document.on('mouseup', this.onMouseup); }); // Autogrow is mandatory beacuse the textarea scrolls away from highlights From bb8762315ed8917e91e2925e339a0677ff20ea6f Mon Sep 17 00:00:00 2001 From: Dean Sofer Date: Mon, 3 Aug 2015 17:28:34 -0700 Subject: [PATCH 3/3] Removed logs --- dist/mention.js | 3 +-- dist/mention.min.js | 2 +- src/mention.es6.js | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/dist/mention.js b/dist/mention.js index 5305e3f..ed4c051 100644 --- a/dist/mention.js +++ b/dist/mention.js @@ -312,7 +312,7 @@ angular.module('ui.mention', []).directive('uiMention', function ($q, $timeout, var _this4 = this; if (event.target == $element[0]) return; - console.log('blur'); + $document.off('mouseup', this.onMouseup); if (!this.searching) return; @@ -324,7 +324,6 @@ angular.module('ui.mention', []).directive('uiMention', function ($q, $timeout, }).bind(this); $element.on('focus', function (event) { - console.log('focus'); $document.on('mouseup', _this2.onMouseup); }); diff --git a/dist/mention.min.js b/dist/mention.min.js index 36dcbff..8cd634f 100644 --- a/dist/mention.min.js +++ b/dist/mention.min.js @@ -1 +1 @@ -"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[],_n=!0,_d=!1,_e=void 0;try{for(var _s,_i=arr[Symbol.iterator]();!(_n=(_s=_i.next()).done)&&(_arr.push(_s.value),!i||_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{!_n&&_i["return"]&&_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr))return arr;if(Symbol.iterator in Object(arr))return sliceIterator(arr,i);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();angular.module("ui.mention",[]).directive("uiMention",function($q,$timeout,$document){return{require:["ngModel","uiMention"],controllerAs:"$mention",link:function($scope,$element,$attrs,_ref){var _ref2=_slicedToArray(_ref,2),ngModel=_ref2[0],uiMention=_ref2[1];uiMention.init(ngModel)},controller:function($element,$scope,$attrs){var _this2=this;this.pattern=this.pattern||/(?:\s+|^)@(\w+(?: \w+)?)$/,this.$element=$element,this.choices=[],this.mentions=[];var ngModel;this.init=function(model){var _this=this;$attrs.ngTrim="false",ngModel=model,ngModel.$parsers.push(function(value){return _this.mentions=_this.mentions.filter(function(mention){return~value.indexOf(_this.label(mention))?value=value.replace(_this.label(mention),_this.encode(mention)):void 0}),_this.render(value),value}),ngModel.$formatters.push(function(){var value=arguments.length<=0||void 0===arguments[0]?"":arguments[0];return value=value.toString(),_this.mentions=_this.mentions.filter(function(mention){return~value.indexOf(_this.encode(mention))?(value=value.replace(_this.encode(mention),_this.label(mention)),!0):!1}),value}),ngModel.$render=function(){$element.val(ngModel.$viewValue||""),_this.render()}},this.render=function(){var html=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return html=(html||"").toString(),_this2.mentions.forEach(function(mention){html=html.replace(_this2.encode(mention),_this2.highlight(mention))}),$element.next().html(html),html},this.highlight=function(choice){return""+this.label(choice)+""},this.decode=function(){var value=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return value?value.replace(/@\[([\s\w]+):[0-9a-z-]+\]/gi,"$1"):""},this.label=function(choice){return choice.first+" "+choice.last},this.encode=function(choice){return"@["+this.label(choice)+":"+choice.id+"]"},this.replace=function(mention){var search=arguments.length<=1||void 0===arguments[1]?this.searching:arguments[1],text=arguments.length<=2||void 0===arguments[2]?ngModel.$viewValue:arguments[2];return text=text.substr(0,search.index+search[0].indexOf("@"))+this.label(mention)+" "+text.substr(search.index+search[0].length)},this.select=function(){var choice=arguments.length<=0||void 0===arguments[0]?this.activeChoice:arguments[0];this.mentions.push(choice),ngModel.$setViewValue(this.replace(choice)),this.cancel(),ngModel.$render()},this.up=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index>0?this.choices[index-1]:this.choices[this.choices.length-1]},this.down=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index"+this.label(choice)+""},this.decode=function(){var value=arguments.length<=0||void 0===arguments[0]?ngModel.$modelValue:arguments[0];return value?value.replace(/@\[([\s\w]+):[0-9a-z-]+\]/gi,"$1"):""},this.label=function(choice){return choice.first+" "+choice.last},this.encode=function(choice){return"@["+this.label(choice)+":"+choice.id+"]"},this.replace=function(mention){var search=arguments.length<=1||void 0===arguments[1]?this.searching:arguments[1],text=arguments.length<=2||void 0===arguments[2]?ngModel.$viewValue:arguments[2];return text=text.substr(0,search.index+search[0].indexOf("@"))+this.label(mention)+" "+text.substr(search.index+search[0].length)},this.select=function(){var choice=arguments.length<=0||void 0===arguments[0]?this.activeChoice:arguments[0];this.mentions.push(choice),ngModel.$setViewValue(this.replace(choice)),this.cancel(),ngModel.$render()},this.up=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index>0?this.choices[index-1]:this.choices[this.choices.length-1]},this.down=function(){var index=this.choices.indexOf(this.activeChoice);this.activeChoice=index { - console.log('focus') $document.on('mouseup', this.onMouseup); });