From 3d2c251b038528c44fe01afc46f8f391e89a4142 Mon Sep 17 00:00:00 2001
From: Ezequiel Bergamaschi <ezequielbergamaschi@gmail.com>
Date: Sun, 20 Apr 2014 23:57:39 -0300
Subject: [PATCH] FloatingTip as bootstrap popover

---
 mindplot/src/main/javascript/NoteIcon.js      |  39 ++-
 .../src/main/javascript/widget/FloatingTip.js | 264 ++----------------
 .../widget/KeyboardShortcutTooltip.js         |  17 +-
 3 files changed, 39 insertions(+), 281 deletions(-)

diff --git a/mindplot/src/main/javascript/NoteIcon.js b/mindplot/src/main/javascript/NoteIcon.js
index b443ce3b..160f0934 100644
--- a/mindplot/src/main/javascript/NoteIcon.js
+++ b/mindplot/src/main/javascript/NoteIcon.js
@@ -31,42 +31,38 @@ mindplot.NoteIcon = new Class({
 
     _registerEvents:function () {
         this._image.setCursor('pointer');
+        var me = this;
 
         if (!this._readOnly) {
-
             // Add on click event to open the editor ...
             this.addEvent('click', function (event) {
-                this._topic.showNoteEditor();
+                me._topic.showNoteEditor();
                 event.stopPropagation();
-            }.bind(this));
+            });
         }
-
-        this._tip = new mindplot.widget.FloatingTip($(this.getImage()._peer._native), {
+        this._tip = new mindplot.widget.FloatingTip($(me.getImage()._peer._native), {
             // Content can also be a function of the target element!
             content:function () {
-                var result = new Element('div');
-                result.setStyles({padding:'5px'});
+                var result = $('<div></div>').css({padding:'5px'});
 
-                var title = new Element('div', {text:$msg('NOTE')});
-                title.setStyles({
-                    'font-weight':'bold',
-                    color:'black',
-                    'padding-bottom':'5px',
-                    width:'100px'
-                });
-                title.inject(result);
+                var title = $('<div></div>').text($msg('NOTE'))
+                    .css({
+                        'font-weight':'bold',
+                        color:'black',
+                        'padding-bottom':'5px',
+                        width:'100px'
+                    });
+                result.append(title);
 
-                var text = new Element('div', {text:this._linksModel.getText()});
-                text.setStyles({
+                var text = $('<div></div>').text(me._linksModel.getText())
+                    .css({
                         'white-space':'pre-wrap',
                         'word-wrap':'break-word'
                     }
                 );
-                text.inject(result);
-
-
+                result.append(text);
                 return result;
-            }.bind(this),
+            },
             html:true,
             position:'bottom',
             arrowOffset:10,
@@ -75,6 +71,7 @@ mindplot.NoteIcon = new Class({
             offset:{x:10, y:20},
             className:'notesTip'
         });
+
     },
 
     getModel:function () {
diff --git a/mindplot/src/main/javascript/widget/FloatingTip.js b/mindplot/src/main/javascript/widget/FloatingTip.js
index e05f1283..c00e4320 100644
--- a/mindplot/src/main/javascript/widget/FloatingTip.js
+++ b/mindplot/src/main/javascript/widget/FloatingTip.js
@@ -15,270 +15,40 @@
  *   See the License for the specific language governing permissions and
  *   limitations under the License.
  */
-
+//FIXME: ver que onda tip en los eventos
 mindplot.widget.FloatingTip = new Class({
     Implements: [Options, mindplot.Events],
 
     options: {
-        position: 'top',
-        center: true,
-        content: 'title',
+        animation: true,
         html: false,
-        balloon: true,
-        arrowSize: 6,
-        arrowOffset: 6,
-        distance: 7,
-        motion: 40,
-        motionOnShow: true,
-        motionOnHide: true,
-        showOn: 'mouseenter',
-        hideOn: 'mouseleave',
-        showDelay: 500,
-        hideDelay: 250,
-        className: 'floating-tip',
-        offset: {x: 0, y: 0},
-        preventHideOnOver: true,
-        fx: { 'duration': 'short' }
+        placement: 'right',
+        selector: false,
+        trigger: 'hover',
+        title: '',
+        content: '',
+        delay: 0,
+        container: false
     },
 
     initialize: function (element, options) {
         this.setOptions(options);
-        this.boundShow = function () {
-            this.show(element);
-        }.bind(this);
-
-        this.boundHide = function () {
-            this.hide(element);
-        }.bind(this);
-
-        if (!['top', 'right', 'bottom', 'left', 'inside'].contains(this.options.position))
-            this.options.position = 'top';
-        this.attach(element);
-    },
-
-    attach: function (element) {
-        if (element.data('hasEvents') !== null) {
-            return;
-        }
-        element.bind(this.options.showOn, this.boundShow);
-        element.bind(this.options.hideOn, this.boundHide);
-        element.data('hasEvents', true);
+        this.element = element;
+        element.popover(this.options);
     },
 
     show: function (element) {
-        var old = document.id(element).retrieve('floatingtip');
-        if (old) {
-            if (old.getStyle('opacity') == 1) {
-                clearTimeout(old.retrieve('timeout'));
-                return this;
-            }
+        if (element) {
+            console.error('element is not necessary');
         }
-        var tip = this._create(element);
-        if (tip == null)
-            return this;
-
-        element.store('floatingtip', tip);
-        this._animate(tip, 'in');
-
-        if (this.options.preventHideOnOver) {
-            tip.addEvent(this.options.showOn, this.boundShow);
-            tip.addEvent(this.options.hideOn, this.boundHide);
-        }
-
-        this.fireEvent('show', [tip, element]);
+        this.element.popover('show');
+        this.fireEvent('show', [this, this.element]);
         return this;
     },
 
     hide: function (element) {
-        var tip = element.retrieve('floatingtip');
-        if (!tip) {
-            if (this.options.position == 'inside') {
-                try {
-                    element = element.getParent().getParent();
-                    tip = element.retrieve('floatingtip');
-                } catch (x) {
-                }
-                if (!tip)
-                    return this;
-            } else {
-                return this;
-            }
-        }
-        this._animate(tip, 'out');
-        this.fireEvent('hide', [tip, element]);
+        this.element.popover('hide');
+        this.fireEvent('hide', [this, element]);
         return this;
-    },
-
-    _create: function (elem) {
-
-        var o = this.options;
-        var oc = o.content;
-        var opos = o.position;
-
-        if (oc == 'title') {
-            oc = 'floatingtitle';
-            if (!elem.get('floatingtitle'))
-                elem.setProperty('floatingtitle', elem.get('title'));
-            elem.set('title', '');
-        }
-
-        var cnt = (typeof(oc) == 'string' ? elem.get(oc) : oc(elem));
-        var cwr = new Element('div').addClass(o.className).setStyle('margin', 0);
-        var tip = new Element('div').addClass(o.className + '-wrapper').setStyles({ 'margin': 0, 'padding': 0, 'z-index': cwr.getStyle('z-index') }).adopt(cwr);
-
-        if (cnt) {
-            if (o.html)
-                cnt.inject(cwr);
-            else
-                cwr.set('text', cnt);
-        } else {
-            return null;
-        }
-
-        var body = document.id(document.body);
-        tip.setStyles({ 'position': 'absolute', 'opacity': 0, 'top': 0, 'left': 0 }).inject(body);
-
-        if (o.balloon && !Browser.ie6) {
-
-            var trg = new Element('div').addClass(o.className + '-triangle').setStyles({ 'margin': 0, 'padding': 0 });
-            var trgSt = { 'border-color': cwr.getStyle('background-color'), 'border-width': o.arrowSize, 'border-style': 'solid', 'width': 0, 'height': 0 };
-
-            switch (opos) {
-                case 'inside':
-                case 'top':
-                    trgSt['border-bottom-width'] = 0;
-                    break;
-                case 'right':
-                    trgSt['border-left-width'] = 0;
-                    trgSt['float'] = 'left';
-                    cwr.setStyle('margin-left', o.arrowSize);
-                    break;
-                case 'bottom':
-                    trgSt['border-top-width'] = 0;
-                    break;
-                case 'left':
-                    trgSt['border-right-width'] = 0;
-                    if (Browser.ie7) {
-                        trgSt['position'] = 'absolute';
-                        trgSt['right'] = 0;
-                    } else {
-                        trgSt['float'] = 'right';
-                    }
-                    cwr.setStyle('margin-right', o.arrowSize);
-                    break;
-            }
-
-            switch (opos) {
-                case 'inside':
-                case 'top':
-                case 'bottom':
-                    trgSt['border-left-color'] = trgSt['border-right-color'] = 'transparent';
-                    trgSt['margin-left'] = o.center ? tip.getSize().x / 2 - o.arrowSize : o.arrowOffset;
-                    break;
-                case 'left':
-                case 'right':
-                    trgSt['border-top-color'] = trgSt['border-bottom-color'] = 'transparent';
-                    trgSt['margin-top'] = o.center ? tip.getSize().y / 2 - o.arrowSize : o.arrowOffset;
-                    break;
-            }
-
-            trg.setStyles(trgSt).inject(tip, (opos == 'top' || opos == 'inside') ? 'bottom' : 'top');
-
-        }
-
-        var tipSz = tip.getSize();
-        var trgC = elem.getCoordinates(body);
-
-        // Paulo: This is hack for Firefox 10.
-        trgC.right = trgC.right == null ? trgC.left : trgC.right;
-        trgC.bottom = trgC.bottom == null ? trgC.top : trgC.bottom;
-        trgC.height = !$defined(trgC.height) ? 0 : trgC.height;
-        trgC.width = !$defined(trgC.width) ? 0 : trgC.width;
-
-        var pos = { x: trgC.left + o.offset.x, y: trgC.top + o.offset.y };
-
-        if (opos == 'inside') {
-            tip.setStyles({ 'width': tip.getStyle('width'), 'height': tip.getStyle('height') });
-            elem.setStyle('position', 'relative').adopt(tip);
-            pos = { x: o.offset.x, y: o.offset.y };
-        } else {
-            switch (opos) {
-                case 'top':
-                    pos.y -= tipSz.y + o.distance;
-                    break;
-                case 'right':
-                    pos.x += trgC.width + o.distance;
-                    break;
-                case 'bottom':
-                    pos.y += trgC.height + o.distance;
-                    break;
-                case 'left':
-                    pos.x -= tipSz.x + o.distance;
-                    break;
-            }
-        }
-
-        if (o.center) {
-            switch (opos) {
-                case 'top':
-                case 'bottom':
-                    pos.x += (trgC.width / 2 - tipSz.x / 2);
-                    break;
-                case 'left':
-                case 'right':
-                    pos.y += (trgC.height / 2 - tipSz.y / 2);
-                    break;
-                case 'inside':
-                    pos.x += (trgC.width / 2 - tipSz.x / 2);
-                    pos.y += (trgC.height / 2 - tipSz.y / 2);
-                    break;
-            }
-        }
-
-        tip.set('morph', o.fx).store('position', pos);
-        tip.setStyles({ 'top': pos.y, 'left': pos.x });
-
-        return tip;
-
-    },
-
-    _animate: function (tip, d) {
-
-        clearTimeout(tip.retrieve('timeout'));
-        tip.store('timeout', (function (t) {
-
-            var o = this.options, din = (d == 'in');
-            var m = { 'opacity': din ? 1 : 0 };
-
-            if ((o.motionOnShow && din) || (o.motionOnHide && !din)) {
-                var pos = t.retrieve('position');
-                if (!pos) return;
-                switch (o.position) {
-                    case 'inside':
-                    case 'top':
-                        m['top'] = din ? [pos.y - o.motion, pos.y] : pos.y - o.motion;
-                        break;
-                    case 'right':
-                        m['left'] = din ? [pos.x + o.motion, pos.x] : pos.x + o.motion;
-                        break;
-                    case 'bottom':
-                        m['top'] = din ? [pos.y + o.motion, pos.y] : pos.y + o.motion;
-                        break;
-                    case 'left':
-                        m['left'] = din ? [pos.x - o.motion, pos.x] : pos.x - o.motion;
-                        break;
-                }
-            }
-
-            t.morph(m);
-            if (!din) t.get('morph').chain(function () {
-                this.dispose();
-            }.bind(t));
-
-        }).delay((d == 'in') ? this.options.showDelay : this.options.hideDelay, this, tip));
-
-        return this;
-
     }
-
 });
diff --git a/mindplot/src/main/javascript/widget/KeyboardShortcutTooltip.js b/mindplot/src/main/javascript/widget/KeyboardShortcutTooltip.js
index 4852cb70..4aed4e65 100644
--- a/mindplot/src/main/javascript/widget/KeyboardShortcutTooltip.js
+++ b/mindplot/src/main/javascript/widget/KeyboardShortcutTooltip.js
@@ -25,26 +25,17 @@ mindplot.widget.KeyboardShortcutTooltip = new Class({
         this._text = text;
 
         var children = buttonElem.children().first();
-        var tipElemId = buttonElem.id + "Tip";
+        var tipElemId = buttonElem.attr('id') + "Tip";
         var tipDiv = $('<div></div>').attr('id', tipElemId);
         tipDiv.append(children);
         buttonElem.append(tipDiv);
 
         this.parent(tipDiv, {
             //Content can also be a function of the target element!
-            content: this._buildContent.pass(buttonElem, this),
+            content: this._buildContent(),
             html: true,
-            position: 'bottom',
-            arrowOffset : 10,
-            center: true,
-            arrowSize: 3,
-            offset : {x:0,y:-2},
-            className: 'keyboardShortcutTip',
-            preventHideOnOver : false,
-            //FIXME: this options are not useful anymore
-            motionOnShow:false,
-            motionOnHide:false,
-            fx: { 'duration': '100' }
+            placement: 'bottom',
+            className: 'keyboardShortcutTip'
         });
 
         tipDiv.on('click', function(e) {