labs-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r1523510 [5/5] - in /labs/panopticon/src/asf/panopticon: __init__.py static/css/panopticon.css static/js/bootstrap.js static/js/bootstrap.min.js static/js/handlebars.js static/js/user-popover.js templates/layout.html
Date Sun, 15 Sep 2013 22:06:30 GMT
Added: labs/panopticon/src/asf/panopticon/static/js/user-popover.js
URL: http://svn.apache.org/viewvc/labs/panopticon/src/asf/panopticon/static/js/user-popover.js?rev=1523510&view=auto
==============================================================================
--- labs/panopticon/src/asf/panopticon/static/js/user-popover.js (added)
+++ labs/panopticon/src/asf/panopticon/static/js/user-popover.js Sun Sep 15 22:06:29 2013
@@ -0,0 +1,223 @@
+(function( $ ) {
+
+    var box_intersection = function(a, b) {
+        var x = {
+            top: Math.max(a.top, b.top),
+            bottom: Math.min(a.bottom, b.bottom),
+            left: Math.max(a.left, b.left),
+            right: Math.min(a.right, b.right)
+        };
+
+        return (x.top < x.bottom && x.left < x.right) ? x : null;
+    };
+
+
+    var box_area = function(box) {
+        if (!box) return 0;
+
+        var width = box.right - box.left,
+                height = box.bottom - box.top;
+
+        return width * height;
+    };
+
+
+    var screen_bounds = function() {
+        var box = {
+            top: $(document).scrollTop(),
+            left: $(document).scrollLeft()
+        };
+
+        box.bottom = box.top + $(window).height();
+        box.right = box.left + $(window).width();
+
+        return box;
+    };
+
+
+    var auto_placement = function(tip, element) {
+        // make tip positioned so that we can get its dimensions
+        $(tip)
+                .remove()
+                .css({ top: 0, left: 0, display: 'block' })
+                .appendTo(document.body)
+
+        var screen_box = screen_bounds(),
+                best_placement = 'bottom',
+                best_visible_area = 0,
+                tip_width = tip.offsetWidth,
+                tip_height = tip.offsetHeight,
+                pos = this.getPosition(),
+                tip_boxes = {
+                    bottom: {top: pos.top + pos.height, left: pos.left + pos.width / 2 -
tip_width / 2},
+                    right: {top: pos.top + pos.height / 2 - tip_height / 2, left: pos.left
+ pos.width},
+                    top: {top: pos.top - tip_height, left: pos.left + pos.width / 2 - tip_width
/ 2},
+                    left: {top: pos.top + pos.height / 2 - tip_height / 2, left: pos.left
- tip_width}
+                },
+                placement_preference = ['bottom', 'right', 'top', 'left'];
+
+        $.each(placement_preference, function(idx, placement) {
+            var tip_box = tip_boxes[placement],
+                    intersection,
+                    visible_area;
+
+            tip_box.right = tip_box.left + tip_width;
+            tip_box.bottom = tip_box.top + tip_height;
+
+            intersection = box_intersection(screen_box, tip_box);
+            visible_area = box_area(intersection);
+
+            if (visible_area > best_visible_area) {
+                best_visible_area = visible_area;
+                best_placement = placement;
+            }
+        });
+
+        return best_placement;
+    };
+
+
+    /* Mix in clickability and auto positioning options to Popover class
+     * ================================================================= */
+    var Popover = $.fn.popover.Constructor;
+
+    $.extend(Popover.prototype, {
+
+        _show: Popover.prototype.show
+        , show: function() {
+            var $tip;
+            this.hoverState = 'in';
+            this._show();
+            $tip = this.tip();
+
+            // workaround for bootstrap 2.2 bug
+            // reattach the tooltip to the parent container so that it does not
+            // inherit CSS styles from the location of the link
+            if (this.options.container) {
+                var offset = $tip.offset();
+                $tip
+                        .detach()
+                        .appendTo(this.options.container)
+                        .offset(offset);
+            }
+
+            if (this.options.clickable) {
+                $tip.mouseenter($.proxy(this.tipEnter, this))
+                        .mouseleave($.proxy(this.tipLeave, this));
+            }
+        }
+
+        , _getOptions: Popover.prototype.getOptions
+        , getOptions: function(options) {
+            options = this._getOptions(options);
+
+            if (options.placement == 'auto') {
+                options.placement = auto_placement;
+            }
+
+            if (options.clickable) {
+                if (typeof options.clickable == 'number') {
+                    options.delay = { show: 1, hide: options.clickable };
+                } else if (!options.delay || !options.delay.hide) {
+                    // if no hide delay is set we can't make it clickable
+                    options.clickable = false;
+                } else if (!options.delay.show) {
+                    // need a show delay of 1 or the parent code doesn't set the
+                    // hoverState needed to make clickability work
+                    options.delay.show = 1;
+                }
+            }
+
+            return options;
+        }
+
+        , tipEnter: function () {
+            this.hoverState = 'in'
+        }
+
+        , tipLeave: function () {
+            var self = this;
+
+            self.hoverState = 'out';
+            setTimeout(function() {
+                if (self.hoverState == 'out') {
+                    self.hide();
+                }
+            }, self.options.delay.hide);
+        }
+
+    });
+
+
+    $.fn.async_popover = function(options, callback) {
+        this.live('mouseover', function() {
+            var $this = $(this),
+                    popover = $this.data('popover');
+
+            // display any existing popover
+            if (popover) {
+                popover.show();
+                return;
+            }
+
+            // initialize a new popover
+            $this.popover(options);
+            popover = $this.data('popover');
+
+            // set up popover loading state
+            $this.attr('data-original-title', 'Loading...');
+            popover.hoverState = 'loading';
+
+            // Only show the loading state if we don't get a timely reponse.
+            // When the data loads quickly this is less jarring than showing the
+            // loading state and then immediately reloading with the real data.
+            setTimeout(function() {
+                if (popover.hoverState == 'loading') {
+                    popover.show();
+                }
+            }, 300);
+
+            callback.call(this, function(title, content) {
+                $this.attr('data-original-title', title);
+                $this.attr('data-content', content);
+                if (popover.hoverState == 'loading' || popover.hoverState == 'in') {
+                    popover.hoverState = 'in';
+                    popover.show();
+                }
+            });
+
+        });
+
+        return this;
+    };
+
+
+    $.fn.user_popover = function(url, template, options) {
+        var cache = {};
+
+        return this.async_popover(options, function(callback) {
+            var username = $(this).data('username'),
+                    data = cache[username];
+
+            // used cached user data if possible
+            if (data) {
+                callback(data.title, data.content);
+                return;
+            }
+
+            var set = function(title, content) {
+                cache[username] = { title: title, content: content };
+                callback(title, content);
+            };
+
+            $.getJSON(url + username)
+                    .success(function(data) {
+                                 set(data.fullname, template(data));
+                             })
+                    .error(function(xhr, status) {
+                               set('Error', 'Error fetching user information.');
+                           });
+        });
+    };
+
+})( window.jQuery );

Modified: labs/panopticon/src/asf/panopticon/templates/layout.html
URL: http://svn.apache.org/viewvc/labs/panopticon/src/asf/panopticon/templates/layout.html?rev=1523510&r1=1523509&r2=1523510&view=diff
==============================================================================
--- labs/panopticon/src/asf/panopticon/templates/layout.html (original)
+++ labs/panopticon/src/asf/panopticon/templates/layout.html Sun Sep 15 22:06:29 2013
@@ -75,7 +75,7 @@
                 <p class="navbar-text pull-right">
                     Logged in as
                     <a href="#" rel="user"
-                       data-username="{{ g.identity.id }}"
+                       data-username="{{ g.identity.name }}"
                             >{{ g.identity.name }}</a>  |
                     <a href="{{ url_for('logout') }}">Sign out</a>
                 </p>
@@ -113,7 +113,29 @@
         </p>
     </div>
 </div>
-<script src="//code.jquery.com/jquery.js"></script>
+<script src="//code.jquery.com/jquery-1.8.3.js"></script>
 <script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
+<script src="{{ url_for('static', filename='js/handlebars.js') }}"></script>
+<script src="{{ url_for('static', filename='js/user-popover.js') }}"></script>
+
+<script id="user-info-template" type="text/x-handlebars-template">
+    {% raw %}
+    <img class="popup-img" src="{{ picture_url }}">
+    <div class="popup-address">
+        <a href="mailto:{{ email_string }}">{{ email }}</a>
+    </div>
+    {% endraw %}
+</script>
+
+<script>
+    $(function() {
+          $('a[rel=user]').user_popover(
+                  {{ url_for('user_info', username='')|tojson|safe }},
+      Handlebars.compile($('#user-info-template').html()),
+      { placement: 'auto', html: true, clickable: 300, trigger: 'hover',
+          container: 'body' }
+    );
+    });
+</script>
 </body>
 </html>



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org


Mime
View raw message