");
+ jQuery(document.body).append(this.options.overlay);
+ }
+ this.options.overlay.bind('click', jQuery.proxy(this.options.editable.turnOff, this.options.editable));
+ }
+ this.options.overlay.show();
+ if (this.options.background === null) {
+ if (jQuery("#halloBackground").length > 0) {
+ this.options.background = jQuery("#halloBackground");
+ } else {
+ this.options.background = jQuery("
");
+ jQuery(document.body).append(this.options.background);
+ }
+ }
+ this.resizeOverlay();
+ this.options.background.show();
+ if (!this.options.originalZIndex) {
+ this.options.originalZIndex = this.options.currentEditable.css("z-index");
+ }
+ return this.options.currentEditable.css('z-index', '350');
+ },
+ resizeOverlay: function() {
+ var offset;
+ offset = this.options.currentEditable.offset();
+ return this.options.background.css({
+ top: offset.top - this.options.padding,
+ left: offset.left - this.options.padding,
+ width: this.options.currentEditable.width() + 2 * this.options.padding,
+ height: this.options.currentEditable.height() + 2 * this.options.padding
+ });
+ },
+ hideOverlay: function() {
+ this.options.visible = false;
+ this.options.overlay.hide();
+ this.options.background.hide();
+ return this.options.currentEditable.css('z-index', this.options.originalZIndex);
+ },
+ _findBackgroundColor: function(jQueryfield) {
+ var color;
+ color = jQueryfield.css("background-color");
+ if (color !== 'rgba(0, 0, 0, 0)' && color !== 'transparent') {
+ return color;
+ }
+ if (jQueryfield.is("body")) {
+ return "white";
+ } else {
+ return this._findBackgroundColor(jQueryfield.parent());
+ }
+ }
+ });
+ })(jQuery);
+
+ (function(jQuery) {
+ return jQuery.widget("IKS.halloreundo", {
+ options: {
+ editable: null,
+ toolbar: null,
+ uuid: '',
+ buttonCssClass: null
+ },
+ populateToolbar: function(toolbar) {
+ var buttonize, buttonset,
+ _this = this;
+ buttonset = jQuery("
");
+ buttonize = function(cmd, label) {
+ var buttonElement;
+ buttonElement = jQuery('
');
+ buttonElement.hallobutton({
+ uuid: _this.options.uuid,
+ editable: _this.options.editable,
+ label: label,
+ icon: cmd === 'undo' ? 'icon-undo' : 'icon-repeat',
+ command: cmd,
+ queryState: false,
+ cssClass: _this.options.buttonCssClass
+ });
+ return buttonset.append(buttonElement);
+ };
+ buttonize("undo", "Undo");
+ buttonize("redo", "Redo");
+ buttonset.hallobuttonset();
+ return toolbar.append(buttonset);
+ }
+ });
+ })(jQuery);
+
+ (function(jQuery) {
+ return jQuery.widget("Liip.hallotoolbarlinebreak", {
+ options: {
+ editable: null,
+ uuid: "",
+ breakAfter: []
+ },
+ populateToolbar: function(toolbar) {
+ var buttonRow, buttonset, buttonsets, queuedButtonsets, row, rowcounter, _i, _j, _len, _len1, _ref;
+ buttonsets = jQuery('.ui-buttonset', toolbar);
+ queuedButtonsets = jQuery();
+ rowcounter = 0;
+ _ref = this.options.breakAfter;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ row = _ref[_i];
+ rowcounter++;
+ buttonRow = "
";
+ for (_j = 0, _len1 = buttonsets.length; _j < _len1; _j++) {
+ buttonset = buttonsets[_j];
+ queuedButtonsets = jQuery(queuedButtonsets).add(jQuery(buttonset));
+ if (jQuery(buttonset).hasClass(row)) {
+ queuedButtonsets.wrapAll(buttonRow);
+ buttonsets = buttonsets.not(queuedButtonsets);
+ queuedButtonsets = jQuery();
+ break;
+ }
+ }
+ }
+ if (buttonsets.length > 0) {
+ rowcounter++;
+ buttonRow = "
";
+ return buttonsets.wrapAll(buttonRow);
+ }
+ }
+ });
+ })(jQuery);
+
+ (function(jQuery) {
+ return jQuery.widget('Hallo.halloToolbarContextual', {
+ toolbar: null,
+ options: {
+ parentElement: 'body',
+ editable: null,
+ toolbar: null
+ },
+ _create: function() {
+ var _this = this;
+ this.toolbar = this.options.toolbar;
+ jQuery(this.options.parentElement).append(this.toolbar);
+ this._bindEvents();
+ return jQuery(window).resize(function(event) {
+ return _this._updatePosition(_this._getPosition(event));
+ });
+ },
+ _getPosition: function(event, selection) {
+ var eventType, position;
+ if (!event) {
+ return;
+ }
+ eventType = event.type;
+ switch (eventType) {
+ case 'keydown':
+ case 'keyup':
+ case 'keypress':
+ return this._getCaretPosition(selection);
+ case 'click':
+ case 'mousedown':
+ case 'mouseup':
+ return position = {
+ top: event.pageY,
+ left: event.pageX
+ };
+ }
+ },
+ _getCaretPosition: function(range) {
+ var newRange, position, tmpSpan;
+ tmpSpan = jQuery("
");
+ newRange = rangy.createRange();
+ newRange.setStart(range.endContainer, range.endOffset);
+ newRange.insertNode(tmpSpan.get(0));
+ position = {
+ top: tmpSpan.offset().top,
+ left: tmpSpan.offset().left
+ };
+ tmpSpan.remove();
+ return position;
+ },
+ setPosition: function() {
+ if (this.options.parentElement !== 'body') {
+ this.options.parentElement = 'body';
+ jQuery(this.options.parentElement).append(this.toolbar);
+ }
+ this.toolbar.css('position', 'absolute');
+ this.toolbar.css('top', this.element.offset().top - 20);
+ return this.toolbar.css('left', this.element.offset().left);
+ },
+ _updatePosition: function(position, selection) {
+ var left, selectionRect, top;
+ if (selection == null) {
+ selection = null;
+ }
+ if (!position) {
+ return;
+ }
+ if (!(position.top && position.left)) {
+ return;
+ }
+ if (selection && !selection.collapsed && selection.nativeRange) {
+ selectionRect = selection.nativeRange.getBoundingClientRect();
+ top = $(window).scrollTop() + selectionRect.top;
+ left = $(window).scrollLeft() + selectionRect.left;
+ } else {
+ top = position.top - 10;
+ left = position.left - this.toolbar.outerWidth() / 2 + 30;
+ }
+ this.toolbar.css('top', top - (this.toolbar.outerHeight() + 10));
+ return this.toolbar.css('left', left);
+ },
+ _bindEvents: function() {
+ var _this = this;
+ this.element.bind('halloselected', function(event, data) {
+ var position;
+ position = _this._getPosition(data.originalEvent, data.selection);
+ if (!position) {
+ return;
+ }
+ _this._updatePosition(position, data.selection);
+ return _this.toolbar.show();
+ });
+ this.element.bind('hallounselected', function(event, data) {
+ return _this.toolbar.hide();
+ });
+ return this.element.bind('hallodeactivated', function(event, data) {
+ return _this.toolbar.hide();
+ });
+ }
+ });
+ })(jQuery);
+
+ (function(jQuery) {
+ return jQuery.widget('Hallo.halloToolbarFixed', {
+ toolbar: null,
options: {
+ parentElement: 'body',
editable: null,
- toolbar: null,
- uuid: '',
- buttonCssClass: null
+ toolbar: null
},
- populateToolbar: function(toolbar) {
- var buttonize, buttonset,
+ _create: function() {
+ var el, widthToAdd,
_this = this;
- buttonset = jQuery("
");
- buttonize = function(alignment) {
- var buttonElement;
- buttonElement = jQuery('
');
- buttonElement.hallobutton({
- uuid: _this.options.uuid,
- editable: _this.options.editable,
- label: alignment,
- command: "justify" + alignment,
- icon: "icon-align-" + (alignment.toLowerCase()),
- cssClass: _this.options.buttonCssClass
- });
- return buttonset.append(buttonElement);
+ this.toolbar = this.options.toolbar;
+ this.toolbar.show();
+ jQuery(this.options.parentElement).append(this.toolbar);
+ this._bindEvents();
+ jQuery(window).resize(function(event) {
+ return _this.setPosition();
+ });
+ if (this.options.parentElement === 'body') {
+ el = jQuery(this.element);
+ widthToAdd = parseFloat(el.css('padding-left'));
+ widthToAdd += parseFloat(el.css('padding-right'));
+ widthToAdd += parseFloat(el.css('border-left-width'));
+ widthToAdd += parseFloat(el.css('border-right-width'));
+ widthToAdd += (parseFloat(el.css('outline-width'))) * 2;
+ widthToAdd += (parseFloat(el.css('outline-offset'))) * 2;
+ return jQuery(this.toolbar).css("width", el.width() + widthToAdd);
+ }
+ },
+ _getPosition: function(event, selection) {
+ var offset, position, width;
+ if (!event) {
+ return;
+ }
+ width = parseFloat(this.element.css('outline-width'));
+ offset = width + parseFloat(this.element.css('outline-offset'));
+ return position = {
+ top: this.element.offset().top - this.toolbar.outerHeight() - offset,
+ left: this.element.offset().left - offset
};
- buttonize("Left");
- buttonize("Center");
- buttonize("Right");
- buttonset.hallobuttonset();
- return toolbar.append(buttonset);
+ },
+ _getCaretPosition: function(range) {
+ var newRange, position, tmpSpan;
+ tmpSpan = jQuery("
");
+ newRange = rangy.createRange();
+ newRange.setStart(range.endContainer, range.endOffset);
+ newRange.insertNode(tmpSpan.get(0));
+ position = {
+ top: tmpSpan.offset().top,
+ left: tmpSpan.offset().left
+ };
+ tmpSpan.remove();
+ return position;
+ },
+ setPosition: function() {
+ if (this.options.parentElement !== 'body') {
+ return;
+ }
+ this.toolbar.css('position', 'absolute');
+ this.toolbar.css('top', this.element.offset().top - this.toolbar.outerHeight());
+ return this.toolbar.css('left', this.element.offset().left + 10);
+ },
+ _updatePosition: function(position) {},
+ _bindEvents: function() {
+ var _this = this;
+ this.element.bind('halloactivated', function(event, data) {
+ _this.setPosition();
+ return _this.toolbar.show();
+ });
+ return this.element.bind('hallodeactivated', function(event, data) {
+ return _this.toolbar.hide();
+ });
}
});
})(jQuery);
@@ -2290,170 +2448,4 @@ http://hallojs.org
});
})(jQuery);
- (function(jQuery) {
- return jQuery.widget('Hallo.halloToolbarContextual', {
- toolbar: null,
- options: {
- parentElement: 'body',
- editable: null,
- toolbar: null
- },
- _create: function() {
- var _this = this;
- this.toolbar = this.options.toolbar;
- jQuery(this.options.parentElement).append(this.toolbar);
- this._bindEvents();
- return jQuery(window).resize(function(event) {
- return _this._updatePosition(_this._getPosition(event));
- });
- },
- _getPosition: function(event, selection) {
- var eventType, position;
- if (!event) {
- return;
- }
- eventType = event.type;
- switch (eventType) {
- case 'keydown':
- case 'keyup':
- case 'keypress':
- return this._getCaretPosition(selection);
- case 'click':
- case 'mousedown':
- case 'mouseup':
- return position = {
- top: event.pageY,
- left: event.pageX
- };
- }
- },
- _getCaretPosition: function(range) {
- var newRange, position, tmpSpan;
- tmpSpan = jQuery("
");
- newRange = rangy.createRange();
- newRange.setStart(range.endContainer, range.endOffset);
- newRange.insertNode(tmpSpan.get(0));
- position = {
- top: tmpSpan.offset().top,
- left: tmpSpan.offset().left
- };
- tmpSpan.remove();
- return position;
- },
- setPosition: function() {
- if (this.options.parentElement !== 'body') {
- this.options.parentElement = 'body';
- jQuery(this.options.parentElement).append(this.toolbar);
- }
- this.toolbar.css('position', 'absolute');
- this.toolbar.css('top', this.element.offset().top - 20);
- return this.toolbar.css('left', this.element.offset().left);
- },
- _updatePosition: function(position) {
- if (!position) {
- return;
- }
- if (!(position.top && position.left)) {
- return;
- }
- this.toolbar.css('top', position.top);
- return this.toolbar.css('left', position.left);
- },
- _bindEvents: function() {
- var _this = this;
- this.element.bind('halloselected', function(event, data) {
- var position;
- position = _this._getPosition(data.originalEvent, data.selection);
- if (!position) {
- return;
- }
- _this._updatePosition(position);
- return _this.toolbar.show();
- });
- this.element.bind('hallounselected', function(event, data) {
- return _this.toolbar.hide();
- });
- return this.element.bind('hallodeactivated', function(event, data) {
- return _this.toolbar.hide();
- });
- }
- });
- })(jQuery);
-
- (function(jQuery) {
- return jQuery.widget('Hallo.halloToolbarFixed', {
- toolbar: null,
- options: {
- parentElement: 'body',
- editable: null,
- toolbar: null
- },
- _create: function() {
- var el, widthToAdd,
- _this = this;
- this.toolbar = this.options.toolbar;
- this.toolbar.show();
- jQuery(this.options.parentElement).append(this.toolbar);
- this._bindEvents();
- jQuery(window).resize(function(event) {
- return _this._updatePosition(_this._getPosition(event));
- });
- if (this.options.parentElement === 'body' && !this.options.floating) {
- el = jQuery(this.element);
- widthToAdd = parseFloat(el.css('padding-left'));
- widthToAdd += parseFloat(el.css('padding-right'));
- widthToAdd += parseFloat(el.css('border-left-width'));
- widthToAdd += parseFloat(el.css('border-right-width'));
- widthToAdd += (parseFloat(el.css('outline-width'))) * 2;
- widthToAdd += (parseFloat(el.css('outline-offset'))) * 2;
- return jQuery(this.toolbar).css("width", el.width() + widthToAdd);
- }
- },
- _getPosition: function(event, selection) {
- var offset, position, width;
- if (!event) {
- return;
- }
- width = parseFloat(this.element.css('outline-width'));
- offset = width + parseFloat(this.element.css('outline-offset'));
- return position = {
- top: this.element.offset().top - this.toolbar.outerHeight() - offset,
- left: this.element.offset().left - offset
- };
- },
- _getCaretPosition: function(range) {
- var newRange, position, tmpSpan;
- tmpSpan = jQuery("
");
- newRange = rangy.createRange();
- newRange.setStart(range.endContainer, range.endOffset);
- newRange.insertNode(tmpSpan.get(0));
- position = {
- top: tmpSpan.offset().top,
- left: tmpSpan.offset().left
- };
- tmpSpan.remove();
- return position;
- },
- setPosition: function() {
- if (this.options.parentElement !== 'body') {
- return;
- }
- this.toolbar.css('position', 'absolute');
- this.toolbar.css('top', this.element.offset().top - this.toolbar.outerHeight());
- return this.toolbar.css('left', this.element.offset().left);
- },
- _updatePosition: function(position) {},
- _bindEvents: function() {
- var _this = this;
- this.element.bind('halloactivated', function(event, data) {
- _this._updatePosition(_this._getPosition(event));
- return _this.toolbar.show();
- });
- return this.element.bind('hallodeactivated', function(event, data) {
- return _this.toolbar.hide();
- });
- }
- });
- })(jQuery);
-
}).call(this);
diff --git a/src/toolbar/contextual.coffee b/src/toolbar/contextual.coffee
index a53c71b..770a051 100644
--- a/src/toolbar/contextual.coffee
+++ b/src/toolbar/contextual.coffee
@@ -55,18 +55,30 @@
@toolbar.css 'top', @element.offset().top - 20
@toolbar.css 'left', @element.offset().left
- _updatePosition: (position) ->
+ _updatePosition: (position, selection=null) ->
return unless position
return unless position.top and position.left
- @toolbar.css 'top', position.top
- @toolbar.css 'left', position.left
+
+ # In case there is a selection, move toolbar on top of it and align with
+ # start of selection.
+ # Else move it on top of current position, center it and move
+ # it slightly to the right.
+ if selection and !selection.collapsed and selection.nativeRange
+ selectionRect = selection.nativeRange.getBoundingClientRect()
+ top = $(window).scrollTop() + selectionRect.top
+ left = $(window).scrollLeft() + selectionRect.left
+ else
+ top = position.top - 10
+ left = position.left - @toolbar.outerWidth() / 2 + 30
+ @toolbar.css 'top', top - (@toolbar.outerHeight() + 10)
+ @toolbar.css 'left', left
_bindEvents: ->
# catch select -> show (and reposition?)
@element.bind 'halloselected', (event, data) =>
position = @_getPosition data.originalEvent, data.selection
return unless position
- @_updatePosition position
+ @_updatePosition position, data.selection
@toolbar.show()
# catch deselect -> hide