Commit 66e5c761 authored by Thomas Park's avatar Thomas Park
Browse files

update bootstrap 3.3.4

parent 93738d76
......@@ -32,10 +32,10 @@
"*/index.html"
],
"dependencies": {
"bootstrap": "~3.3.2"
"bootstrap": "~3.3.4"
},
"devDependencies": {
"bootstrap-sass-official": "~3.3.2",
"bootstrap-sass-official": "~3.3.4",
"font-awesome": "~4.0.0",
"html5shiv": "~3.7.0",
"respond": "~1.4.2"
......
{
"name": "bootstrap-sass",
"version": "3.3.3",
"version": "3.3.4",
"homepage": "https://github.com/twbs/bootstrap-sass",
"authors": [
"Thomas McDonald",
......@@ -37,13 +37,13 @@
"dependencies": {
"jquery": ">= 1.9.0"
},
"_release": "3.3.3",
"_release": "3.3.4",
"_resolution": {
"type": "version",
"tag": "v3.3.3",
"commit": "ed0a2bfdc9e33c3f350306252ee8da9da47d6107"
"tag": "v3.3.4",
"commit": "283bb45d032a94f66cca0888dc9cbc93f44353e0"
},
"_source": "git://github.com/twbs/bootstrap-sass.git",
"_target": "~3.3.2",
"_target": "~3.3.4",
"_originalSource": "bootstrap-sass-official"
}
\ No newline at end of file
# Changelog
## 3.3.4
No Sass-specific changes.
Framework version: Bootstrap **v3.3.4**
## 3.3.3
This is a re-packaged release of 3.3.2.1 (v3.3.2+1).
......
# Bootstrap for Sass [![Gem Version](https://badge.fury.io/rb/bootstrap-sass.svg)](http://badge.fury.io/rb/bootstrap-sass) [![Bower Version](https://badge.fury.io/bo/bootstrap-sass.svg)](http://badge.fury.io/bo/bootstrap-sass) [![Build Status](http://img.shields.io/travis/twbs/bootstrap-sass.svg)](http://travis-ci.org/twbs/bootstrap-sass)
# Bootstrap for Sass
[![Gem Version](https://badge.fury.io/rb/bootstrap-sass.svg)](http://badge.fury.io/rb/bootstrap-sass)
[![npm version](https://img.shields.io/npm/v/bootstrap-sass.svg?style=flat)](https://www.npmjs.com/package/bootstrap-sass)
[![Bower Version](https://badge.fury.io/bo/bootstrap-sass.svg)](http://badge.fury.io/bo/bootstrap-sass)
[![Build Status](http://img.shields.io/travis/twbs/bootstrap-sass.svg)](http://travis-ci.org/twbs/bootstrap-sass)
`bootstrap-sass` is a Sass-powered version of [Bootstrap](http://github.com/twbs/bootstrap), ready to drop right into your Sass powered applications.
......@@ -17,13 +21,13 @@ Please see the appropriate guide for your environment of choice:
In your Gemfile you need to add the `bootstrap-sass` gem, and ensure that the `sass-rails` gem is present - it is added to new Rails applications by default.
```ruby
gem 'bootstrap-sass', '~> 3.3.3'
gem 'bootstrap-sass', '~> 3.3.4'
gem 'sass-rails', '>= 3.2'
```
`bundle install` and restart your server to make the files available through the pipeline.
Import Bootstrap styles in `app/assets/stylesheets/application.css.scss`:
Import Bootstrap styles in `app/assets/stylesheets/application.scss`:
```scss
// "bootstrap-sprockets" must be imported before "bootstrap" and "bootstrap/variables"
......@@ -33,11 +37,11 @@ Import Bootstrap styles in `app/assets/stylesheets/application.css.scss`:
`bootstrap-sprockets` must be imported before `bootstrap` for the icon fonts to work.
Make sure the file has `.css.scss` extension (or `.css.sass` for Sass syntax). If you have just generated a new Rails app,
Make sure the file has `.scss` extension (or `.sass` for Sass syntax). If you have just generated a new Rails app,
it may come with a `.css` file instead. If this file exists, it will be served instead of Sass, so rename it:
```console
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.css.scss
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
```
Then, remove all the `//= require` and `//= require_tree` statements from the file. Instead, use `@import` to import Sass files.
......@@ -51,6 +55,11 @@ Require Bootstrap Javascripts in `app/assets/javascripts/application.js`:
//= require bootstrap-sprockets
```
`bootstrap-sprockets` and `bootstrap` [should not both be included](https://github.com/twbs/bootstrap-sass/issues/829#issuecomment-75153827) in `application.js`.
`bootstrap-sprockets` provides individual Bootstrap Javascript files (`alert.js` or `dropdown.js`, for example), while
`bootstrap` provides a concatenated file containing all Bootstrap Javascripts.
#### Bower with Rails
When using [bootstrap-sass Bower package](#c-bower) instead of the gem in Rails, configure assets in `config/application.rb`:
......@@ -64,10 +73,10 @@ end
# Precompile Bootstrap fonts
config.assets.precompile << %r(bootstrap-sass/assets/fonts/bootstrap/[\w-]+\.(?:eot|svg|ttf|woff2?)$)
# Minimum Sass number precision required by bootstrap-sass
::Sass::Script::Number.precision = [8, ::Sass::Script::Number.precision].max
::Sass::Script::Value::Number.precision = [8, ::Sass::Script::Value::Number.precision].max
```
Replace Bootstrap `@import` statements in `application.css.scss` with:
Replace Bootstrap `@import` statements in `application.scss` with:
```scss
$icon-font-path: "bootstrap-sass/assets/fonts/bootstrap/";
......@@ -188,7 +197,7 @@ Precision is set for Rails and Compass automatically.
When using ruby Sass compiler standalone or with the Bower version you can set it with:
```ruby
::Sass::Script::Number.precision = [8, ::Sass::Script::Number.precision].max
::Sass::Script::Value::Number.precision = [8, ::Sass::Script::Value::Number.precision].max
```
#### Sass: Autoprefixer
......@@ -241,7 +250,7 @@ When using bootstrap-sass with Compass, Sprockets, or Mincer, you **must** impor
### Sass
Import Bootstrap into a Sass file (for example, application.css.scss) to get all of Bootstrap's styles, mixins and variables!
Import Bootstrap into a Sass file (for example, application.scss) to get all of Bootstrap's styles, mixins and variables!
```scss
@import "bootstrap";
......@@ -265,7 +274,20 @@ $navbar-default-color: $light-orange;
## Version
`bootstrap-sass` version reflects the upstream version, with an additional number for Sass-specific changes.
Bootstrap for Sass version may differ from the upstream version in the last number, known as
[MINOR](http://semver.org/spec/v2.0.0.html). The minor version may be ahead of the corresponding upstream minor.
This happens when we need to release Sass-specific changes.
Before v3.3.2, Bootstrap for Sass version used to reflect the upstream version, with an additional number for
Sass-specific changes. This was changed due to Bower and npm compatibility issues.
The upstream versions vs the Bootstrap for Sass versions are:
| Upstream | Sass |
|---------:|--------:|
| 3.3.4 | 3.3.4 |
| 3.3.2 | 3.3.3 |
| <= 3.3.1 | 3.3.1.x |
Always refer to [CHANGELOG.md](/CHANGELOG.md) when upgrading.
......@@ -295,7 +317,7 @@ To convert a specific branch or version, pass the branch name or the commit hash
The latest converter script is located [here][converter] and does the following:
* Converts upstream bootstrap LESS files to its matching SCSS file.
* Copies all upstream JavaScript into `assets/javascripts/bootstrap`, an Sprockets manifest at `assets/javascripts/bootstrap-sprockets.js`, and a concatenation at `assets/javascripts/bootstrap.js`.
* Copies all upstream JavaScript into `assets/javascripts/bootstrap`, a Sprockets manifest at `assets/javascripts/bootstrap-sprockets.js`, and a concatenation at `assets/javascripts/bootstrap.js`.
* Copies all upstream font files into `assets/fonts/bootstrap`.
* Sets `Bootstrap::BOOTSTRAP_SHA` in [version.rb][version] to the branch sha.
......@@ -316,15 +338,15 @@ and a [significant number of other contributors][contrib].
## You're in good company
bootstrap-sass is used to build some awesome projects all over the web, including
[Diaspora](http://diasporaproject.org/), [rails_admin](https://github.com/sferik/rails_admin),
[Diaspora](https://diasporafoundation.org/), [rails_admin](https://github.com/sferik/rails_admin),
Michael Hartl's [Rails Tutorial](http://railstutorial.org/), [gitlabhq](http://gitlabhq.com/) and
[kandan](http://kandanapp.com/).
[kandan](http://kandan.io/).
[converter]: https://github.com/twbs/bootstrap-sass/blob/master/tasks/converter/less_conversion.rb
[version]: https://github.com/twbs/bootstrap-sass/blob/master/lib/bootstrap-sass/version.rb
[contrib]: https://github.com/twbs/bootstrap-sass/graphs/contributors
[antirequire]: https://github.com/twbs/bootstrap-sass/issues/79#issuecomment-4428595
[jsdocs]: http://getbootstrap.com/javascript/#transitions
[sass-precision]: http://sass-lang.com/documentation/Sass/Script/Number.html#precision-class_method
[sass-precision]: http://sass-lang.com/documentation/Sass/Script/Value/Number.html#precision%3D-class_method
[mincer]: https://github.com/nodeca/mincer
[autoprefixer]: https://github.com/ai/autoprefixer
......@@ -4,9 +4,9 @@
//= require ./bootstrap/carousel
//= require ./bootstrap/collapse
//= require ./bootstrap/dropdown
//= require ./bootstrap/modal
//= require ./bootstrap/scrollspy
//= require ./bootstrap/tab
//= require ./bootstrap/transition
//= require ./bootstrap/scrollspy
//= require ./bootstrap/modal
//= require ./bootstrap/tooltip
//= require ./bootstrap/popover
/*!
* Bootstrap v3.3.2 (http://getbootstrap.com)
* Bootstrap v3.3.4 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
......@@ -17,7 +17,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: transition.js v3.3.2
* Bootstrap: transition.js v3.3.4
* http://getbootstrap.com/javascript/#transitions
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -77,7 +77,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: alert.js v3.3.2
* Bootstrap: alert.js v3.3.4
* http://getbootstrap.com/javascript/#alerts
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -96,7 +96,7 @@ if (typeof jQuery === 'undefined') {
$(el).on('click', dismiss, this.close)
}
Alert.VERSION = '3.3.2'
Alert.VERSION = '3.3.4'
Alert.TRANSITION_DURATION = 150
......@@ -172,7 +172,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: button.js v3.3.2
* Bootstrap: button.js v3.3.4
* http://getbootstrap.com/javascript/#buttons
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -192,7 +192,7 @@ if (typeof jQuery === 'undefined') {
this.isLoading = false
}
Button.VERSION = '3.3.2'
Button.VERSION = '3.3.4'
Button.DEFAULTS = {
loadingText: 'loading...'
......@@ -289,7 +289,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: carousel.js v3.3.2
* Bootstrap: carousel.js v3.3.4
* http://getbootstrap.com/javascript/#carousel
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -307,10 +307,10 @@ if (typeof jQuery === 'undefined') {
this.$element = $(element)
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.paused =
this.sliding =
this.interval =
this.$active =
this.paused = null
this.sliding = null
this.interval = null
this.$active = null
this.$items = null
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
......@@ -320,7 +320,7 @@ if (typeof jQuery === 'undefined') {
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
}
Carousel.VERSION = '3.3.2'
Carousel.VERSION = '3.3.4'
Carousel.TRANSITION_DURATION = 600
......@@ -527,7 +527,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: collapse.js v3.3.2
* Bootstrap: collapse.js v3.3.4
* http://getbootstrap.com/javascript/#collapse
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -544,7 +544,8 @@ if (typeof jQuery === 'undefined') {
var Collapse = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Collapse.DEFAULTS, options)
this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
this.transitioning = null
if (this.options.parent) {
......@@ -556,13 +557,12 @@ if (typeof jQuery === 'undefined') {
if (this.options.toggle) this.toggle()
}
Collapse.VERSION = '3.3.2'
Collapse.VERSION = '3.3.4'
Collapse.TRANSITION_DURATION = 350
Collapse.DEFAULTS = {
toggle: true,
trigger: '[data-toggle="collapse"]'
toggle: true
}
Collapse.prototype.dimension = function () {
......@@ -700,7 +700,7 @@ if (typeof jQuery === 'undefined') {
var data = $this.data('bs.collapse')
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data && options.toggle && option == 'show') options.toggle = false
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
if (typeof option == 'string') data[option]()
})
......@@ -731,7 +731,7 @@ if (typeof jQuery === 'undefined') {
var $target = getTargetFromTrigger($this)
var data = $target.data('bs.collapse')
var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
var option = data ? 'toggle' : $this.data()
Plugin.call($target, option)
})
......@@ -739,7 +739,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: dropdown.js v3.3.2
* Bootstrap: dropdown.js v3.3.4
* http://getbootstrap.com/javascript/#dropdowns
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -759,7 +759,7 @@ if (typeof jQuery === 'undefined') {
$(element).on('click.bs.dropdown', this.toggle)
}
Dropdown.VERSION = '3.3.2'
Dropdown.VERSION = '3.3.4'
Dropdown.prototype.toggle = function (e) {
var $this = $(this)
......@@ -812,7 +812,7 @@ if (typeof jQuery === 'undefined') {
return $this.trigger('click')
}
var desc = ' li:not(.divider):visible a'
var desc = ' li:not(.disabled):visible a'
var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
if (!$items.length) return
......@@ -901,7 +901,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: modal.js v3.3.2
* Bootstrap: modal.js v3.3.4
* http://getbootstrap.com/javascript/#modals
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -919,9 +919,12 @@ if (typeof jQuery === 'undefined') {
this.options = options
this.$body = $(document.body)
this.$element = $(element)
this.$backdrop =
this.$dialog = this.$element.find('.modal-dialog')
this.$backdrop = null
this.isShown = null
this.originalBodyPad = null
this.scrollbarWidth = 0
this.ignoreBackdropClick = false
if (this.options.remote) {
this.$element
......@@ -932,7 +935,7 @@ if (typeof jQuery === 'undefined') {
}
}
Modal.VERSION = '3.3.2'
Modal.VERSION = '3.3.4'
Modal.TRANSITION_DURATION = 300
Modal.BACKDROP_TRANSITION_DURATION = 150
......@@ -966,6 +969,12 @@ if (typeof jQuery === 'undefined') {
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
this.$dialog.on('mousedown.dismiss.bs.modal', function () {
that.$element.one('mouseup.dismiss.bs.modal', function (e) {
if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
})
})
this.backdrop(function () {
var transition = $.support.transition && that.$element.hasClass('fade')
......@@ -977,7 +986,6 @@ if (typeof jQuery === 'undefined') {
.show()
.scrollTop(0)
if (that.options.backdrop) that.adjustBackdrop()
that.adjustDialog()
if (transition) {
......@@ -993,7 +1001,7 @@ if (typeof jQuery === 'undefined') {
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
transition ?
that.$element.find('.modal-dialog') // wait for modal to slide in
that.$dialog // wait for modal to slide in
.one('bsTransitionEnd', function () {
that.$element.trigger('focus').trigger(e)
})
......@@ -1022,6 +1030,9 @@ if (typeof jQuery === 'undefined') {
.removeClass('in')
.attr('aria-hidden', true)
.off('click.dismiss.bs.modal')
.off('mouseup.dismiss.bs.modal')
this.$dialog.off('mousedown.dismiss.bs.modal')
$.support.transition && this.$element.hasClass('fade') ?
this.$element
......@@ -1082,12 +1093,17 @@ if (typeof jQuery === 'undefined') {
var doAnimate = $.support.transition && animate
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
.prependTo(this.$element)
.on('click.dismiss.bs.modal', $.proxy(function (e) {
.appendTo(this.$body)
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
if (this.ignoreBackdropClick) {
this.ignoreBackdropClick = false
return
}
if (e.target !== e.currentTarget) return
this.options.backdrop == 'static'
? this.$element[0].focus.call(this.$element[0])
: this.hide.call(this)
? this.$element[0].focus()
: this.hide()
}, this))
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
......@@ -1123,16 +1139,9 @@ if (typeof jQuery === 'undefined') {
// these following methods are used to handle overflowing modals
Modal.prototype.handleUpdate = function () {
if (this.options.backdrop) this.adjustBackdrop()
this.adjustDialog()
}
Modal.prototype.adjustBackdrop = function () {
this.$backdrop
.css('height', 0)
.css('height', this.$element[0].scrollHeight)
}
Modal.prototype.adjustDialog = function () {
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
......@@ -1150,17 +1159,23 @@ if (typeof jQuery === 'undefined') {
}
Modal.prototype.checkScrollbar = function () {
this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight
var fullWindowWidth = window.innerWidth
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
var documentElementRect = document.documentElement.getBoundingClientRect()
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
}
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
this.scrollbarWidth = this.measureScrollbar()
}
Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
this.originalBodyPad = document.body.style.paddingRight || ''
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
}
Modal.prototype.resetScrollbar = function () {
this.$body.css('padding-right', '')
this.$body.css('padding-right', this.originalBodyPad)
}
Modal.prototype.measureScrollbar = function () { // thx walsh
......@@ -1226,7 +1241,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: tooltip.js v3.3.2
* Bootstrap: tooltip.js v3.3.4
* http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
......@@ -1242,17 +1257,17 @@ if (typeof jQuery === 'undefined') {
// ===============================
var Tooltip = function (element, options) {
this.type =
this.options =
this.enabled =
this.timeout =
this.hoverState =
this.type = null
this.options = null
this.enabled = null
this.timeout = null
this.hoverState = null
this.$element = null
this.init('tooltip', element, options)
}
Tooltip.VERSION = '3.3.2'
Tooltip.VERSION = '3.3.4'
Tooltip.TRANSITION_DURATION = 150
......@@ -1279,6 +1294,10 @@ if (typeof jQuery === 'undefined') {
this.options = this.getOptions(options)
this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
}
var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) {
......@@ -1499,10 +1518,10 @@ if (typeof jQuery === 'undefined') {
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
}
Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
this.arrow()
.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isHorizontal ? 'top' : 'left', '')
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isVertical ? 'top' : 'left', '')
}
Tooltip.prototype.setContent = function () {
......@@ -1515,7 +1534,7 @@ if (typeof jQuery === 'undefined') {
Tooltip.prototype.hide = function (callback) {
var that = this
var $tip = this.tip()
var $tip = $(this.$tip)
var e = $.Event('hide.bs.' + this.type)
function complete() {
......@@ -1532,7 +1551,7 @@ if (typeof jQuery === 'undefined') {
$tip.removeClass('in')
$.support.transition && this.$tip.hasClass('fade') ?
$.support.transition && $tip.hasClass('fade') ?
$tip
.one('bsTransitionEnd', complete)
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
......@@ -1676,7 +1695,7 @@ if (typeof jQuery === 'undefined') {
var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option
if (!data && option == 'destroy') return
if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
})
......@@ -1699,7 +1718,7 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/* ========================================================================
* Bootstrap: popover.js v3.3.2
* Bootstrap: popover.js v3.3.4
* http://getbootstrap.com/javascript/#popovers
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
......@@ -1719,7 +1738,7 @@ if (typeof jQuery === 'undefined') {
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
Popover.VERSION = '3.3.2'
Popover.VERSION = '3.3.4'
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
placement: 'right',
......@@ -1775,11 +1794,6 @@ if (typeof jQuery === 'undefined') {
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
}
Popover.prototype.tip = function () {
if (!this