Skip to content

Commit

Permalink
delayHide & delayShow Options (#17)
Browse files Browse the repository at this point in the history
* #15 Now supporting the `delayHide` and `delayShow` options.

* #15 Code climate annoyances
  • Loading branch information
nadnoslen committed Feb 1, 2017
1 parent b6abdb0 commit d22b88c
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 29 deletions.
1 change: 1 addition & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ engines:
- df6b6fd64376dd46e0ca8e8d127f2da9
- 6abf5ab49d988083ea87bcc3abc4d25a
- 5ee693d9305f81516289eae029e132ab
- 8819bc8e9cc6430d74f0b269b0eea495
config:
languages:
- ruby
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ A component that contains all of the markup associated with the popover. You ca

The reason this addon requires **Ember-2.3.0+** is because this particular component uses the _hash_ helper.

**Be aware that when you nest either the content or title it will be automatically treated as html.**

##### Arguments

* _All of the properties listed in the `Popover` mixin_.
Expand Down Expand Up @@ -126,6 +128,8 @@ here: [http://getbootstrap.com/javascript/#popovers-options](http://getbootstrap
* `animation?` (aliased to `animation`)- **Default** `true`
* `content` - **Default** `''`
* `delay` - **Default** `0`
* `delayHide` - **Default** `undefined`
* `delayShow` - **Default** `undefined`
* `html?` (aliased to `html`) - **Default** `false`
* `placement` - **Default** `'right'`
* `popoverContainer` - **Default** `false`
Expand Down
36 changes: 34 additions & 2 deletions addon/mixins/popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ export default Ember.Mixin.create({
* Object structure is: `delay: { "show": 500, "hide": 100 }`.
*/
delay: 0,
/**
* Delay hiding the popover (ms) - does not apply to manual trigger type.
*/
delayHide: undefined,
/**
* Delay showing the popover (ms) - does not apply to manual trigger type.
*/
delayShow: undefined,
/**
* Insert HTML into the popover. If false, jQuery's text method will be used to insert content into
* the DOM. Use text if you're worried about XSS attacks.
Expand Down Expand Up @@ -84,10 +92,34 @@ export default Ember.Mixin.create({
*/
getOptions() {
const hash =
this.getProperties('animation', 'content', 'delay', 'html', 'placement', 'selector', 'title');
this.getProperties('animation', 'content', 'html', 'placement', 'selector', 'title');
hash.container = this.get('popoverContainer');
hash.delay = this.get('_delayComputed');
hash.template = this.get('popoverTemplate');
hash.trigger = this.get('popoverTrigger');
Ember.Logger.info(hash);
return hash;
}
},
/**
* If a number is supplied, delay is applied to both hide/show.
*
* Object structure is: `delay: { "show": 500, "hide": 100 }`.
* @private
*/
_delayComputed: Ember.computed('delay', 'delayHide', 'delayShow', function () {
const delayObject = {
hide: this.get('delay'),
show: this.get('delay')
};

if (Ember.isPresent(this.get('delayHide'))) {
Ember.set(delayObject, 'hide', this.get('delayHide'));
}

if (Ember.isPresent(this.get('delayShow'))) {
Ember.set(delayObject, 'show', this.get('delayShow'));
}

return delayObject;
})
});
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@
</div>

<h4><code>content</code> (block)</h4>
<div class="alert alert-info">
<p>
<i class="fa fa-info-circle"></i>
Content specified in the nested block is automatically treated as html
(you do not have to set <code>html?=true</code>).
</p>
</div>

<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover as |popover|}}
Expand All @@ -87,6 +95,7 @@
{{/popover.content}}
{{/twbs-popover}}
</div>

<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover as |popover|}}
Expand All @@ -105,7 +114,7 @@
<h4><code>delay</code></h4>
<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover delay=1500 as |popover|}}
{{#twbs-popover delay=500 as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click This Button</button>
{{/popover.trigger}}
Expand All @@ -116,7 +125,7 @@
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover delay=1500 as |popover|}}
<pre>\{{#twbs-popover delay=500 as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click This Button&lt;/button>
\{{/popover.trigger}}
Expand All @@ -129,48 +138,93 @@
</div>
</div>

<h4><code>html?=false</code> (DEFAULT)</h4>
<h4><code>delayShow</code></h4>
<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover html?=false as |popover|}}
{{#twbs-popover delayShow=500 as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click This Button</button>
{{/popover.trigger}}
{{#popover.content}}
<p>This is treated as plain-text.</p>
Click again to hide.
{{/popover.content}}
{{/twbs-popover}}
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover html?=false as |popover|}}
<pre>\{{#twbs-popover delayShow=500 as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click This Button&lt;/button>
\{{/popover.trigger}}
\{{#popover.content}}
&lt;p>This is treated as plain-text.&lt;/p>
Click again to hide.
\{{/popover.content}}
\{{/twbs-popover}}
</pre>
{{!-- @formatter:on --}}
</div>
</div>

<h4><code>html?=true</code></h4>
<h4><code>delayHide</code></h4>
<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover html?=true as |popover|}}
{{#twbs-popover delayHide=500 as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click This Button</button>
{{/popover.trigger}}
{{#popover.content}}
<p>This is treated as <strong>html</strong>.</p>
Click again to hide.
{{/popover.content}}
{{/twbs-popover}}
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover html?=true as |popover|}}
<pre>\{{#twbs-popover delayHide=500 as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click This Button&lt;/button>
\{{/popover.trigger}}
\{{#popover.content}}
Click again to hide.
\{{/popover.content}}
\{{/twbs-popover}}
</pre>
{{!-- @formatter:on --}}
</div>
</div>

<h4><code>html?=false</code> (DEFAULT)</h4>
<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover html?=false content="<p>This is treated as plain-text.</p>" as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click This Button</button>
{{/popover.trigger}}
{{/twbs-popover}}
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover html?=false content="&lt;p>This is treated as plain-text.&lt;/p>" as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click This Button&lt;/button>
\{{/popover.trigger}}
\{{/twbs-popover}}
</pre>
{{!-- @formatter:on --}}
</div>
</div>

<h4><code>html?=true</code></h4>
<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover html?=true content="<p>This is treated as <strong>HTML</strong>.</p>" as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click This Button</button>
{{/popover.trigger}}
{{/twbs-popover}}
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover html?=true content="&lt;p>This is treated as &lt;strong>HTML&lt;/strong>.&lt;/p>" as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click This Button&lt;/button>
\{{/popover.trigger}}
Expand Down Expand Up @@ -318,6 +372,14 @@
</div>

<h4><code>title</code> (block)</h4>
<div class="alert alert-info">
<p>
<i class="fa fa-info-circle"></i>
A Title specified in the nested block is automatically treated as html
(you do not have to set <code>html?=true</code>).
</p>
</div>

<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover as |popover|}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<h3>HTML-Based Popover Content</h3>

<div class="alert alert-warning">
<p>
Keep in mind that when you use either the <code>twbs-popover/content</code> or <code>twbs-popover/title</code>
components, the generated popover will be treated as html content.
</p>
</div>

<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
{{#twbs-popover popoverTrigger="click" as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click This Button</button>
{{/popover.trigger}}
Expand All @@ -18,7 +25,7 @@
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
<pre>\{{#twbs-popover popoverTrigger="click" as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click This Button&lt;/button>
\{{/popover.trigger}}
Expand All @@ -40,7 +47,7 @@

<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
{{#twbs-popover popoverTrigger="click" as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click This Button</button>
{{/popover.trigger}}
Expand All @@ -55,7 +62,7 @@
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
<pre>\{{#twbs-popover popoverTrigger="click" as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click This Button&lt;/button>
\{{/popover.trigger}}
Expand All @@ -76,7 +83,7 @@

<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover html?=true as |popover|}}
{{#twbs-popover as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click this button</button>
{{/popover.trigger}}
Expand All @@ -90,7 +97,7 @@
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover html?=true as |popover|}}
<pre>\{{#twbs-popover as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click this button&lt;/button>
\{{/popover.trigger}}
Expand All @@ -110,7 +117,7 @@

<div class="row">
<div class="col-sm-4 form-group">
{{#twbs-popover html?=true as |popover|}}
{{#twbs-popover as |popover|}}
{{#popover.trigger}}
<button class="btn btn-default">Click this button</button>
{{/popover.trigger}}
Expand All @@ -124,7 +131,7 @@
</div>
<div class="col-sm-8">
{{!-- @formatter:off --}}
<pre>\{{#twbs-popover html?=true as |popover|}}
<pre>\{{#twbs-popover as |popover|}}
\{{#popover.trigger}}
&lt;button class="btn btn-default">Click this button&lt;/button>
\{{/popover.trigger}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
<li>
The <code>hide</code>, <code>show</code>, and <code>toggle</code> actions (analogous to the
<a href="http://getbootstrap.com/javascript/#popovers-methods" target="_blank">Bootstrap popover methods</a>) of
the <code>\{{twbs-popover}}</code> will be available when you add them to the <em>as</em>.
the <code>\{{twbs-popover}}</code> will be available when you add them to the
<code>\{{#twbs-popover ...}}</code> <em>as</em>.
</li>
<li>
When using these actions the <code>popoverTrigger</code> should be set to <code>manual</code> for these actions
Expand Down Expand Up @@ -116,7 +117,7 @@
The <code>onShow</code>, <code>onShown</code>, <code>onHide</code>, <code>onHidden</code>, and
<code>onInserted</code> events (analogous to the
<a href="http://getbootstrap.com/javascript/#popovers-events" target="_blank">Bootstrap popover events</a>) of
the <code>\{{twbs-popover}}</code> can be hooked into your component's, controller's, or route's actions. In
the <code>\{{twbs-popover}}</code> can be hooked into your component's, controller's, or route's actions. In
this example I have the <code>onShow</code>, <code>onShown</code>, etc. properties set to actions (of the
exact same name) in my component that is responsible for rendering the <code>\{{twbs-popover}}</code>.
</li>
Expand Down
24 changes: 18 additions & 6 deletions tests/unit/mixins/popover-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ test('when requesting the options hash the defaults are all present', function (
const options = popover.getOptions();
assert.equal(options.animation, true);
assert.equal(options.content, '');
assert.equal(options.delay, 0);
assert.equal(options.delay.hide, 0);
assert.equal(options.delay.show, 0);
assert.equal(options.html, false);
assert.equal(options.placement, 'right');
assert.equal(options.container, false);
Expand All @@ -34,9 +35,20 @@ test('when requesting the options hash the the popoverTrigger shows up under tri
assert.equal(options.trigger, 'focus');
});

// Replace this with your real tests.
test('it works', function (assert) {
let PopoverObject = Ember.Object.extend(PopoverMixin);
let subject = PopoverObject.create();
assert.ok(subject);
test('when the delay value is set both show and hide are the same', function (assert) {
const popoverMixin = Ember.Object.extend(PopoverMixin).create({delay: 500});
assert.equal(popoverMixin.get('_delayComputed.hide'), 500);
assert.equal(popoverMixin.get('_delayComputed.show'), 500);
});

test('when only the delay-show value is set ', function (assert) {
const popoverMixin = Ember.Object.extend(PopoverMixin).create({delayShow: 500});
assert.equal(popoverMixin.get('_delayComputed.hide'), 0);
assert.equal(popoverMixin.get('_delayComputed.show'), 500);
});

test('when only the delay-hide value is set ', function (assert) {
const popoverMixin = Ember.Object.extend(PopoverMixin).create({delayHide: 500});
assert.equal(popoverMixin.get('_delayComputed.hide'), 500);
assert.equal(popoverMixin.get('_delayComputed.show'), 0);
});

0 comments on commit d22b88c

Please sign in to comment.