1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | !function( $ ) {
|
23 |
|
24 | "use strict"
|
25 |
|
26 | |
27 |
|
28 |
|
29 | var transitionEnd
|
30 |
|
31 | $(document).ready(function () {
|
32 |
|
33 | $.support.transition = (function () {
|
34 | var thisBody = document.body || document.documentElement
|
35 | , thisStyle = thisBody.style
|
36 | , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
|
37 | return support
|
38 | })()
|
39 |
|
40 |
|
41 | if ( $.support.transition ) {
|
42 | transitionEnd = "TransitionEnd"
|
43 | if ( $.browser.webkit ) {
|
44 | transitionEnd = "webkitTransitionEnd"
|
45 | } else if ( $.browser.mozilla ) {
|
46 | transitionEnd = "transitionend"
|
47 | } else if ( $.browser.opera ) {
|
48 | transitionEnd = "oTransitionEnd"
|
49 | }
|
50 | }
|
51 |
|
52 | })
|
53 |
|
54 |
|
55 | |
56 |
|
57 |
|
58 | var Twipsy = function ( element, options ) {
|
59 | this.$element = $(element)
|
60 | this.options = options
|
61 | this.enabled = true
|
62 | this.fixTitle()
|
63 | }
|
64 |
|
65 | Twipsy.prototype = {
|
66 |
|
67 | show: function() {
|
68 | var pos
|
69 | , actualWidth
|
70 | , actualHeight
|
71 | , placement
|
72 | , $tip
|
73 | , tp
|
74 |
|
75 | if (this.hasContent() && this.enabled) {
|
76 | $tip = this.tip()
|
77 | this.setContent()
|
78 |
|
79 | if (this.options.animate) {
|
80 | $tip.addClass('fade')
|
81 | }
|
82 |
|
83 | $tip
|
84 | .remove()
|
85 | .css({ top: 0, left: 0, display: 'block' })
|
86 | .prependTo(document.body)
|
87 |
|
88 | pos = $.extend({}, this.$element.offset(), {
|
89 | width: this.$element[0].offsetWidth
|
90 | , height: this.$element[0].offsetHeight
|
91 | })
|
92 |
|
93 | actualWidth = $tip[0].offsetWidth
|
94 | actualHeight = $tip[0].offsetHeight
|
95 |
|
96 | placement = maybeCall(this.options.placement, this, [ $tip[0], this.$element[0] ])
|
97 |
|
98 | switch (placement) {
|
99 | case 'below':
|
100 | tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}
|
101 | break
|
102 | case 'above':
|
103 | tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}
|
104 | break
|
105 | case 'left':
|
106 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}
|
107 | break
|
108 | case 'right':
|
109 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}
|
110 | break
|
111 | }
|
112 |
|
113 | $tip
|
114 | .css(tp)
|
115 | .addClass(placement)
|
116 | .addClass('in')
|
117 | }
|
118 | }
|
119 |
|
120 | , setContent: function () {
|
121 | var $tip = this.tip()
|
122 | $tip.find('.twipsy-inner')[this.options.html ? 'html' : 'text'](this.getTitle())
|
123 | $tip[0].className = 'twipsy'
|
124 | }
|
125 |
|
126 | , hide: function() {
|
127 | var that = this
|
128 | , $tip = this.tip()
|
129 |
|
130 | $tip.removeClass('in')
|
131 |
|
132 | function removeElement () {
|
133 | $tip.remove()
|
134 | }
|
135 |
|
136 | $.support.transition && this.$tip.hasClass('fade') ?
|
137 | $tip.bind(transitionEnd, removeElement) :
|
138 | removeElement()
|
139 | }
|
140 |
|
141 | , fixTitle: function() {
|
142 | var $e = this.$element
|
143 | if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
|
144 | $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
|
145 | }
|
146 | }
|
147 |
|
148 | , hasContent: function () {
|
149 | return this.getTitle()
|
150 | }
|
151 |
|
152 | , getTitle: function() {
|
153 | var title
|
154 | , $e = this.$element
|
155 | , o = this.options
|
156 |
|
157 | this.fixTitle()
|
158 |
|
159 | if (typeof o.title == 'string') {
|
160 | title = $e.attr(o.title == 'title' ? 'data-original-title' : o.title)
|
161 | } else if (typeof o.title == 'function') {
|
162 | title = o.title.call($e[0])
|
163 | }
|
164 |
|
165 | title = ('' + title).replace(/(^\s*|\s*$)/, "")
|
166 |
|
167 | return title || o.fallback
|
168 | }
|
169 |
|
170 | , tip: function() {
|
171 | return this.$tip = this.$tip || $('<div class="twipsy" />').html(this.options.template)
|
172 | }
|
173 |
|
174 | , validate: function() {
|
175 | if (!this.$element[0].parentNode) {
|
176 | this.hide()
|
177 | this.$element = null
|
178 | this.options = null
|
179 | }
|
180 | }
|
181 |
|
182 | , enable: function() {
|
183 | this.enabled = true
|
184 | }
|
185 |
|
186 | , disable: function() {
|
187 | this.enabled = false
|
188 | }
|
189 |
|
190 | , toggleEnabled: function() {
|
191 | this.enabled = !this.enabled
|
192 | }
|
193 |
|
194 | , toggle: function () {
|
195 | this[this.tip().hasClass('in') ? 'hide' : 'show']()
|
196 | }
|
197 |
|
198 | }
|
199 |
|
200 |
|
201 | |
202 |
|
203 |
|
204 | function maybeCall ( thing, ctx, args ) {
|
205 | return typeof thing == 'function' ? thing.apply(ctx, args) : thing
|
206 | }
|
207 |
|
208 | |
209 |
|
210 |
|
211 | $.fn.twipsy = function (options) {
|
212 | $.fn.twipsy.initWith.call(this, options, Twipsy, 'twipsy')
|
213 | return this
|
214 | }
|
215 |
|
216 | $.fn.twipsy.initWith = function (options, Constructor, name) {
|
217 | var twipsy
|
218 | , binder
|
219 | , eventIn
|
220 | , eventOut
|
221 |
|
222 | if (options === true) {
|
223 | return this.data(name)
|
224 | } else if (typeof options == 'string') {
|
225 | twipsy = this.data(name)
|
226 | if (twipsy) {
|
227 | twipsy[options]()
|
228 | }
|
229 | return this
|
230 | }
|
231 |
|
232 | options = $.extend({}, $.fn[name].defaults, options)
|
233 |
|
234 | function get(ele) {
|
235 | var twipsy = $.data(ele, name)
|
236 |
|
237 | if (!twipsy) {
|
238 | twipsy = new Constructor(ele, $.fn.twipsy.elementOptions(ele, options))
|
239 | $.data(ele, name, twipsy)
|
240 | }
|
241 |
|
242 | return twipsy
|
243 | }
|
244 |
|
245 | function enter() {
|
246 | var twipsy = get(this)
|
247 | twipsy.hoverState = 'in'
|
248 |
|
249 | if (options.delayIn == 0) {
|
250 | twipsy.show()
|
251 | } else {
|
252 | twipsy.fixTitle()
|
253 | setTimeout(function() {
|
254 | if (twipsy.hoverState == 'in') {
|
255 | twipsy.show()
|
256 | }
|
257 | }, options.delayIn)
|
258 | }
|
259 | }
|
260 |
|
261 | function leave() {
|
262 | var twipsy = get(this)
|
263 | twipsy.hoverState = 'out'
|
264 | if (options.delayOut == 0) {
|
265 | twipsy.hide()
|
266 | } else {
|
267 | setTimeout(function() {
|
268 | if (twipsy.hoverState == 'out') {
|
269 | twipsy.hide()
|
270 | }
|
271 | }, options.delayOut)
|
272 | }
|
273 | }
|
274 |
|
275 | if (!options.live) {
|
276 | this.each(function() {
|
277 | get(this)
|
278 | })
|
279 | }
|
280 |
|
281 | if (options.trigger != 'manual') {
|
282 | binder = options.live ? 'live' : 'bind'
|
283 | eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus'
|
284 | eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'
|
285 | this[binder](eventIn, enter)[binder](eventOut, leave)
|
286 | }
|
287 |
|
288 | return this
|
289 | }
|
290 |
|
291 | $.fn.twipsy.Twipsy = Twipsy
|
292 |
|
293 | $.fn.twipsy.defaults = {
|
294 | animate: true
|
295 | , delayIn: 0
|
296 | , delayOut: 0
|
297 | , fallback: ''
|
298 | , placement: 'above'
|
299 | , html: false
|
300 | , live: false
|
301 | , offset: 0
|
302 | , title: 'title'
|
303 | , trigger: 'hover'
|
304 | , template: '<div class="twipsy-arrow"></div><div class="twipsy-inner"></div>'
|
305 | }
|
306 |
|
307 | $.fn.twipsy.rejectAttrOptions = [ 'title' ]
|
308 |
|
309 | $.fn.twipsy.elementOptions = function(ele, options) {
|
310 | var data = $(ele).data()
|
311 | , rejects = $.fn.twipsy.rejectAttrOptions
|
312 | , i = rejects.length
|
313 |
|
314 | while (i--) {
|
315 | delete data[rejects[i]]
|
316 | }
|
317 |
|
318 | return $.extend({}, options, data)
|
319 | }
|
320 |
|
321 | }( window.jQuery || window.ender ); |
\ | No newline at end of file |