Skip to content
This repository
Browse code

Hover bubble UI overhaul.

* Backbone
* Show event
* Display groups (for fast show/hide switching)
* Right alignment mode
* Slide animations
  • Loading branch information...
commit e66b62181163f3839e00ba8ad642d92acc774165 1 parent 14a8fd5
Max Goodman chromakode authored spladug committed
70 r2/r2/public/static/css/reddit.less
@@ -892,41 +892,67 @@ a.author { margin-right: 0.5em; }
892 892 cursor: help;
893 893 }
894 894
895   -.help-bubble {
  895 +.hover-bubble {
896 896 display: none;
897 897 position: absolute;
898   - width: 35em;
899 898 background: white;
900 899 color: #333;
901 900 border: 1px solid gray;
902 901 padding: 3px;
903 902 box-shadow: 0 2px 10px rgba(0,0,0,.25);
904   -}
  903 + z-index: 100;
905 904
906   -.help-bubble p, .help-bubble form {
907   - margin: .5em;
908   -}
  905 + &:before, &:after {
  906 + position: absolute;
  907 + display: block;
  908 + content: '';
  909 + }
909 910
910   -.help-bubble:before, .help-bubble:after {
911   - position: absolute;
912   - right: 8px;
913   - display: block;
914   - content: '';
915   - border: 9px solid transparent;
916   -}
  911 + &.anchor-top {
  912 + &:before, &:after {
  913 + right: 8px;
  914 + border: 9px solid transparent;
  915 + }
917 916
918   -.help-bubble:before {
919   - top: -19px;
920   - border-bottom-color: gray;
921   -}
  917 + &:before {
  918 + top: -19px;
  919 + border-bottom-color: gray;
  920 + }
  921 +
  922 + &:after {
  923 + top: -18px;
  924 + border-bottom-color: white;
  925 + }
  926 + }
  927 +
  928 + &.anchor-right {
  929 + &:before, &:after {
  930 + top: 8px;
  931 + border: 9px solid transparent;
  932 + }
922 933
923   -.help-bubble:after {
924   - top: -18px;
925   - border-bottom-color: white;
  934 + &:before {
  935 + right: -19px;
  936 + border-left-color: gray;
  937 + }
  938 +
  939 + &:after {
  940 + right: -18px;
  941 + border-left-color: white;
  942 + }
  943 + }
926 944 }
927 945
928   -.help-bubble a:hover {
929   - text-decoration: underline
  946 +.help-bubble {
  947 + width: 35em;
  948 +
  949 + p, form {
  950 + margin: .5em;
  951 + }
  952 +
  953 + a:hover {
  954 + text-decoration: underline
  955 + }
930 956 }
931 957
932 958 .infotext {
133 r2/r2/public/static/js/ui.js
@@ -24,7 +24,10 @@ r.ui.init = function() {
24 24 $('body > .content > :not(.infobar):first').before(infobar)
25 25 }
26 26
27   - r.ui.HelpBubble.init()
  27 + $('.help-bubble').each(function(idx, el) {
  28 + $(el).data('HelpBubble', new r.ui.Bubble({el: el}))
  29 + })
  30 +
28 31 r.ui.PermissionEditor.init()
29 32 }
30 33
@@ -131,46 +134,122 @@ r.ui.Form.prototype = $.extend(new r.ui.Base(), {
131 134 }
132 135 })
133 136
134   -r.ui.HelpBubble = function(el) {
135   - r.ui.Base.call(this, el)
136   - this.$el.hover($.proxy(this, 'queueShow'), $.proxy(this, 'queueHide'))
137   - this.$parent = this.$el.parent()
138   - this.$parent.hover($.proxy(this, 'queueShow'), $.proxy(this, 'queueHide'))
139   - this.$parent.click($.proxy(this, 'queueShow'))
140   -}
141   -r.ui.HelpBubble.init = function() {
142   - $('.help-bubble').each(function(idx, el) {
143   - $(el).data('HelpBubble', new r.ui.HelpBubble(el))
144   - })
145   -}
146   -r.ui.HelpBubble.prototype = $.extend(new r.ui.Base(), {
  137 +r.ui.Bubble = Backbone.View.extend({
147 138 showDelay: 150,
148 139 hideDelay: 750,
  140 + animateDuration: 150,
  141 +
  142 + initialize: function() {
  143 + this.$el.hover($.proxy(this, 'queueShow'), $.proxy(this, 'queueHide'))
  144 + this.$parent = this.options.parent || this.$el.parent()
  145 + this.$parent.hover($.proxy(this, 'queueShow'), $.proxy(this, 'queueHide'))
  146 + this.$parent.click($.proxy(this, 'queueShow'))
  147 + },
  148 +
  149 + position: function() {
  150 + var parentPos = this.$parent.offset(),
  151 + bodyOffset = $('body').offset(),
  152 + offsetX, offsetY
  153 + if (this.$el.is('.anchor-top')) {
  154 + offsetX = this.$parent.outerWidth(true) - this.$el.outerWidth(true)
  155 + offsetY = this.$parent.outerHeight(true) + 5
  156 + this.$el.css({
  157 + left: parentPos.left + offsetX,
  158 + top: parentPos.top + offsetY - bodyOffset.top
  159 + })
  160 + } else if (this.$el.is('.anchor-right')) {
  161 + offsetX = 16
  162 + offsetY = 0
  163 + parentPos.right = $(window).width() - parentPos.left
  164 + this.$el.css({
  165 + right: parentPos.right + offsetX,
  166 + top: parentPos.top + offsetY - bodyOffset.top
  167 + })
  168 + }
  169 + },
149 170
150 171 show: function() {
151 172 this.cancelTimeout()
  173 + if (this.$el.is(':visible')) {
  174 + return
  175 + }
  176 +
  177 + this.trigger('show')
152 178
153 179 $('body').append(this.$el)
154 180
155   - var parentPos = this.$parent.offset()
156   - this.$el
157   - .show()
158   - .offset({
159   - left: parentPos.left + this.$parent.outerWidth(true) - this.$el.outerWidth(true),
160   - top: parentPos.top + this.$parent.outerHeight(true) + 5
161   - })
  181 + this.render()
  182 + this.position()
  183 + this.$el.css('opacity', 1).show()
  184 +
  185 + var isSwitch = this.options.group && this.options.group.current && this.options.group.current != this
  186 + if (isSwitch) {
  187 + this.options.group.current.hideNow()
  188 + } else {
  189 + this._animate('show')
  190 + }
  191 +
  192 + if (this.options.group) {
  193 + this.options.group.current = this
  194 + }
  195 + },
  196 +
  197 + hideNow: function() {
  198 + this.cancelTimeout()
  199 + if (this.options.group) {
  200 + this.options.group.current = null
  201 + }
  202 + this.$el.hide()
  203 + this.$parent.append(this.$el)
162 204 },
163 205
164 206 hide: function(callback) {
165   - this.$el.fadeOut(150, $.proxy(function() {
166   - this.$el.hide()
167   - this.$parent.append(this.$el)
168   - if (callback) {
169   - callback()
170   - }
  207 + if (!this.$el.is(':visible')) {
  208 + callback && callback()
  209 + return
  210 + }
  211 +
  212 + this._animate('hide', $.proxy(function() {
  213 + this.hideNow()
  214 + callback && callback()
171 215 }, this))
172 216 },
173 217
  218 + _animate: function(action, callback) {
  219 + if (!this.animateDuration) {
  220 + callback && callback()
  221 + return
  222 + }
  223 +
  224 + var animProp, animOffset
  225 + if (this.$el.is('.anchor-top')) {
  226 + animProp = 'top'
  227 + animOffset = '-=5'
  228 + } else if (this.$el.is('.anchor-right')) {
  229 + animProp = 'right'
  230 + animOffset = '-=5'
  231 + }
  232 + var curOffset = this.$el.css(animProp)
  233 +
  234 + hideProps = {'opacity': 0}
  235 + hideProps[animProp] = animOffset
  236 + showProps = {'opacity': 1}
  237 + showProps[animProp] = curOffset
  238 +
  239 + var start, end
  240 + if (action == 'show') {
  241 + start = hideProps
  242 + end = showProps
  243 + } else if (action == 'hide') {
  244 + start = showProps
  245 + end = hideProps
  246 + }
  247 +
  248 + this.$el
  249 + .css(start)
  250 + .animate(end, this.animateDuration, callback)
  251 + },
  252 +
174 253 cancelTimeout: function() {
175 254 if (this.timeout) {
176 255 clearTimeout(this.timeout)
2  r2/r2/templates/spotlightlisting.html
@@ -49,7 +49,7 @@
49 49
50 50 <div class="help help-hoverable">
51 51 ${_("what's this?")}
52   - <div id="spotlight-help" class="help-bubble">
  52 + <div id="spotlight-help" class="hover-bubble help-bubble anchor-top">
53 53 <div class="help-section help-promoted">
54 54 <p>
55 55 ${text_with_links(

0 comments on commit e66b621

Please sign in to comment.
Something went wrong with that request. Please try again.