"),f=d[0].innerHTML;e.addClass(b.iconclass),d[0].innerHTML="",d.append(e),f&&""!==f&&d.append(" "+f)}return c._lastToolDefinition=angular.copy(b),a(d)(c)};g.tools={},g._parent={disabled:!0,showHtml:!1,queryFormatBlockState:function(){return!1},queryCommandState:function(){return!1}};var k={$window:f,$editor:function(){return g._parent},isDisabled:function(){return"function"!=typeof this.$eval("disabled")&&this.$eval("disabled")||this.$eval("disabled()")||"html"!==this.name&&this.$editor().showHtml||this.$parent.disabled||this.$editor().disabled},displayActiveToolClass:function(a){return a?g.classes.toolbarButtonActive:""},executeAction:e};angular.forEach(g.toolbar,function(a){var b=angular.element("");b.addClass(g.classes.toolbarGroup),angular.forEach(a,function(a){g.tools[a]=angular.extend(g.$new(!0),d[a],k,{name:a}),g.tools[a].$element=j(d[a],g.tools[a]),b.append(g.tools[a].$element)}),h.append(b)}),g.updateToolDisplay=function(a,b,c){var d=g.tools[a];if(d){if(d._lastToolDefinition&&!c&&(b=angular.extend({},d._lastToolDefinition,b)),null===b.buttontext&&null===b.iconclass&&null===b.display)throw'textAngular Error: Tool Definition for updating "'+a+'" does not have a valid display/iconclass/buttontext value';null===b.buttontext&&delete b.buttontext,null===b.iconclass&&delete b.iconclass,null===b.display&&delete b.display;var e=j(b,d);d.$element.replaceWith(e),d.$element=e}},g.addTool=function(a,b,c,e){g.tools[a]=angular.extend(g.$new(!0),d[a],k,{name:a}),g.tools[a].$element=j(d[a],g.tools[a]);var f;void 0===c&&(c=g.toolbar.length-1),f=angular.element(h.children()[c]),void 0===e?(f.append(g.tools[a].$element),g.toolbar[c][g.toolbar[c].length-1]=a):(f.children().eq(e).after(g.tools[a].$element),g.toolbar[c][e]=a)},b.registerToolbar(g),g.$on("$destroy",function(){b.unregisterToolbar(g.name)})}}}])}()}({},function(){return this}());
\ No newline at end of file
diff --git a/lib/main.js b/lib/main.js
index 50d42c7f..a1e7f50c 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -100,7 +100,7 @@ textAngular.directive("textAngular", [
// shim the .one till fixed
var _func = function(){
_element.off(event, _func);
- action();
+ action.apply(this, arguments);
};
_element.on(event, _func);
}, 100);
@@ -186,7 +186,7 @@ textAngular.directive("textAngular", [
scope.displayElements.popover.css('display', 'block');
scope.reflowPopover(_el);
$animate.addClass(scope.displayElements.popover, 'in');
- oneEvent(element, 'click keyup', function(){scope.hidePopover();});
+ oneEvent($document.find('body'), 'click keyup', function(){scope.hidePopover();});
};
scope.reflowPopover = function(_el){
/* istanbul ignore if: catches only if near bottom of editor */
@@ -249,38 +249,24 @@ textAngular.directive("textAngular", [
x: Math.max(0, startPosition.width + (event.clientX - startPosition.x)),
y: Math.max(0, startPosition.height + (event.clientY - startPosition.y))
};
- var applyImageSafeCSS = function(_el, css){
- _el = angular.element(_el);
- if(_el[0].tagName.toLowerCase() === 'img'){
- if(css.height){
- _el.attr('height', css.height);
- delete css.height;
- }
- if(css.width){
- _el.attr('width', css.width);
- delete css.width;
- }
- }
- _el.css(css);
- };
+
if(event.shiftKey){
// keep ratio
var newRatio = pos.y / pos.x;
- applyImageSafeCSS(_el, {
- width: ratio > newRatio ? pos.x : pos.y / ratio,
- height: ratio > newRatio ? pos.x * ratio : pos.y
- });
- }else{
- applyImageSafeCSS(_el, {
- width: pos.x,
- height: pos.y
- });
+ pos.x = ratio > newRatio ? pos.x : pos.y / ratio;
+ pos.y = ratio > newRatio ? pos.x * ratio : pos.y;
}
+ el = angular.element(_el);
+ el.attr('height', Math.max(0, pos.y));
+ el.attr('width', Math.max(0, pos.x));
+
// reflow the popover tooltip
scope.reflowResizeOverlay(_el);
};
$document.find('body').on('mousemove', mousemove);
- oneEvent(scope.displayElements.resize.overlay, 'mouseup', function(){
+ oneEvent($document.find('body'), 'mouseup', function(event){
+ event.preventDefault();
+ event.stopPropagation();
$document.find('body').off('mousemove', mousemove);
scope.showPopover(_el);
});
@@ -291,7 +277,7 @@ textAngular.directive("textAngular", [
scope.displayElements.resize.anchors[3].on('mousedown', resizeMouseDown);
scope.reflowResizeOverlay(_el);
- oneEvent(element, 'click', function(){scope.hideResizeOverlay();});
+ oneEvent($document.find('body'), 'click', function(){scope.hideResizeOverlay();});
};
/* istanbul ignore next: pretty sure phantomjs won't test this */
scope.hideResizeOverlay = function(){
diff --git a/lib/taBind.js b/lib/taBind.js
index 47bba3f2..b557e1ae 100644
--- a/lib/taBind.js
+++ b/lib/taBind.js
@@ -93,7 +93,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
if(!_isReadonly && _isContentEditable){
var content = ngModel.$undoManager.undo();
if(typeof content !== "undefined" && content !== null){
- element[0].innerHTML = content;
+ _setInnerHTML(content);
_setViewValue(content, false);
/* istanbul ignore else: browser catch */
if(element[0].childNodes.length) taSelection.setSelectionToElementEnd(element[0].childNodes[element[0].childNodes.length-1]);
@@ -107,7 +107,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
if(!_isReadonly && _isContentEditable){
var content = ngModel.$undoManager.redo();
if(typeof content !== "undefined" && content !== null){
- element[0].innerHTML = content;
+ _setInnerHTML(content);
_setViewValue(content, false);
/* istanbul ignore else: browser catch */
if(element[0].childNodes.length) taSelection.setSelectionToElementEnd(element[0].childNodes[element[0].childNodes.length-1]);
@@ -131,6 +131,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
if(ngModel.$viewValue !== '') ngModel.$setViewValue('');
if(triggerUndo && ngModel.$undoManager.current() !== '') ngModel.$undoManager.push('');
}else{
+ _reApplyOnSelectorHandlers();
if(ngModel.$viewValue !== _val){
ngModel.$setViewValue(_val);
if(triggerUndo) ngModel.$undoManager.push(_val);
@@ -416,7 +417,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
}
var val = _compileHtml();
if(_defaultVal !== '' && val.trim() === ''){
- element[0].innerHTML = _defaultVal;
+ _setInnerHTML(_defaultVal);
taSelection.setSelectionToElementStart(element.children()[0]);
}
var triggerUndo = _lastKey !== event.keyCode && UNDO_TRIGGER_KEYS.test(event.keyCode);
@@ -513,7 +514,6 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
$timeout(function(){
dropFired = false;
_setViewValue();
- _reApplyOnSelectorHandlers();
}, 100);
}
};
diff --git a/src/textAngular.js b/src/textAngular.js
index d13903ed..d56ba6a6 100644
--- a/src/textAngular.js
+++ b/src/textAngular.js
@@ -886,7 +886,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
if(!_isReadonly && _isContentEditable){
var content = ngModel.$undoManager.undo();
if(typeof content !== "undefined" && content !== null){
- element[0].innerHTML = content;
+ _setInnerHTML(content);
_setViewValue(content, false);
/* istanbul ignore else: browser catch */
if(element[0].childNodes.length) taSelection.setSelectionToElementEnd(element[0].childNodes[element[0].childNodes.length-1]);
@@ -900,7 +900,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
if(!_isReadonly && _isContentEditable){
var content = ngModel.$undoManager.redo();
if(typeof content !== "undefined" && content !== null){
- element[0].innerHTML = content;
+ _setInnerHTML(content);
_setViewValue(content, false);
/* istanbul ignore else: browser catch */
if(element[0].childNodes.length) taSelection.setSelectionToElementEnd(element[0].childNodes[element[0].childNodes.length-1]);
@@ -924,6 +924,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
if(ngModel.$viewValue !== '') ngModel.$setViewValue('');
if(triggerUndo && ngModel.$undoManager.current() !== '') ngModel.$undoManager.push('');
}else{
+ _reApplyOnSelectorHandlers();
if(ngModel.$viewValue !== _val){
ngModel.$setViewValue(_val);
if(triggerUndo) ngModel.$undoManager.push(_val);
@@ -1209,7 +1210,7 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
}
var val = _compileHtml();
if(_defaultVal !== '' && val.trim() === ''){
- element[0].innerHTML = _defaultVal;
+ _setInnerHTML(_defaultVal);
taSelection.setSelectionToElementStart(element.children()[0]);
}
var triggerUndo = _lastKey !== event.keyCode && UNDO_TRIGGER_KEYS.test(event.keyCode);
@@ -1306,7 +1307,6 @@ angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'
$timeout(function(){
dropFired = false;
_setViewValue();
- _reApplyOnSelectorHandlers();
}, 100);
}
};
@@ -1548,7 +1548,7 @@ textAngular.directive("textAngular", [
// shim the .one till fixed
var _func = function(){
_element.off(event, _func);
- action();
+ action.apply(this, arguments);
};
_element.on(event, _func);
}, 100);
@@ -1634,7 +1634,7 @@ textAngular.directive("textAngular", [
scope.displayElements.popover.css('display', 'block');
scope.reflowPopover(_el);
$animate.addClass(scope.displayElements.popover, 'in');
- oneEvent(element, 'click keyup', function(){scope.hidePopover();});
+ oneEvent($document.find('body'), 'click keyup', function(){scope.hidePopover();});
};
scope.reflowPopover = function(_el){
/* istanbul ignore if: catches only if near bottom of editor */
@@ -1697,38 +1697,24 @@ textAngular.directive("textAngular", [
x: Math.max(0, startPosition.width + (event.clientX - startPosition.x)),
y: Math.max(0, startPosition.height + (event.clientY - startPosition.y))
};
- var applyImageSafeCSS = function(_el, css){
- _el = angular.element(_el);
- if(_el[0].tagName.toLowerCase() === 'img'){
- if(css.height){
- _el.attr('height', css.height);
- delete css.height;
- }
- if(css.width){
- _el.attr('width', css.width);
- delete css.width;
- }
- }
- _el.css(css);
- };
+
if(event.shiftKey){
// keep ratio
var newRatio = pos.y / pos.x;
- applyImageSafeCSS(_el, {
- width: ratio > newRatio ? pos.x : pos.y / ratio,
- height: ratio > newRatio ? pos.x * ratio : pos.y
- });
- }else{
- applyImageSafeCSS(_el, {
- width: pos.x,
- height: pos.y
- });
+ pos.x = ratio > newRatio ? pos.x : pos.y / ratio;
+ pos.y = ratio > newRatio ? pos.x * ratio : pos.y;
}
+ el = angular.element(_el);
+ el.attr('height', Math.max(0, pos.y));
+ el.attr('width', Math.max(0, pos.x));
+
// reflow the popover tooltip
scope.reflowResizeOverlay(_el);
};
$document.find('body').on('mousemove', mousemove);
- oneEvent(scope.displayElements.resize.overlay, 'mouseup', function(){
+ oneEvent($document.find('body'), 'mouseup', function(event){
+ event.preventDefault();
+ event.stopPropagation();
$document.find('body').off('mousemove', mousemove);
scope.showPopover(_el);
});
@@ -1739,7 +1725,7 @@ textAngular.directive("textAngular", [
scope.displayElements.resize.anchors[3].on('mousedown', resizeMouseDown);
scope.reflowResizeOverlay(_el);
- oneEvent(element, 'click', function(){scope.hideResizeOverlay();});
+ oneEvent($document.find('body'), 'click', function(){scope.hideResizeOverlay();});
};
/* istanbul ignore next: pretty sure phantomjs won't test this */
scope.hideResizeOverlay = function(){
diff --git a/test/textAngular.spec.js b/test/textAngular.spec.js
index 00e879cc..db482263 100644
--- a/test/textAngular.spec.js
+++ b/test/textAngular.spec.js
@@ -975,11 +975,11 @@ describe('textAngular', function(){
editorScope.hidePopover();
expect(editorScope.displayElements.popover.hasClass('in')).toBe(false);
});
- it('on click in editor', function(){
- element.triggerHandler('click');
+ it('on click in editor', inject(function($document){
+ $document.find('body').triggerHandler('click');
editorScope.$parent.$digest();
expect(editorScope.displayElements.popover.hasClass('in')).toBe(false);
- });
+ }));
it('should prevent mousedown from propagating up from popover', function(){
var event;
if(angular.element === jQuery){