Skip to content

Commit d22b88c

Browse files
authored
delayHide & delayShow Options (#17)
* #15 Now supporting the `delayHide` and `delayShow` options. * #15 Code climate annoyances
1 parent b6abdb0 commit d22b88c

File tree

7 files changed

+148
-29
lines changed

7 files changed

+148
-29
lines changed

.codeclimate.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ engines:
1010
- df6b6fd64376dd46e0ca8e8d127f2da9
1111
- 6abf5ab49d988083ea87bcc3abc4d25a
1212
- 5ee693d9305f81516289eae029e132ab
13+
- 8819bc8e9cc6430d74f0b269b0eea495
1314
config:
1415
languages:
1516
- ruby

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ A component that contains all of the markup associated with the popover. You ca
6565

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

68+
**Be aware that when you nest either the content or title it will be automatically treated as html.**
69+
6870
##### Arguments
6971

7072
* _All of the properties listed in the `Popover` mixin_.
@@ -126,6 +128,8 @@ here: [http://getbootstrap.com/javascript/#popovers-options](http://getbootstrap
126128
* `animation?` (aliased to `animation`)- **Default** `true`
127129
* `content` - **Default** `''`
128130
* `delay` - **Default** `0`
131+
* `delayHide` - **Default** `undefined`
132+
* `delayShow` - **Default** `undefined`
129133
* `html?` (aliased to `html`) - **Default** `false`
130134
* `placement` - **Default** `'right'`
131135
* `popoverContainer` - **Default** `false`

addon/mixins/popover.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ export default Ember.Mixin.create({
2525
* Object structure is: `delay: { "show": 500, "hide": 100 }`.
2626
*/
2727
delay: 0,
28+
/**
29+
* Delay hiding the popover (ms) - does not apply to manual trigger type.
30+
*/
31+
delayHide: undefined,
32+
/**
33+
* Delay showing the popover (ms) - does not apply to manual trigger type.
34+
*/
35+
delayShow: undefined,
2836
/**
2937
* Insert HTML into the popover. If false, jQuery's text method will be used to insert content into
3038
* the DOM. Use text if you're worried about XSS attacks.
@@ -84,10 +92,34 @@ export default Ember.Mixin.create({
8492
*/
8593
getOptions() {
8694
const hash =
87-
this.getProperties('animation', 'content', 'delay', 'html', 'placement', 'selector', 'title');
95+
this.getProperties('animation', 'content', 'html', 'placement', 'selector', 'title');
8896
hash.container = this.get('popoverContainer');
97+
hash.delay = this.get('_delayComputed');
8998
hash.template = this.get('popoverTemplate');
9099
hash.trigger = this.get('popoverTrigger');
100+
Ember.Logger.info(hash);
91101
return hash;
92-
}
102+
},
103+
/**
104+
* If a number is supplied, delay is applied to both hide/show.
105+
*
106+
* Object structure is: `delay: { "show": 500, "hide": 100 }`.
107+
* @private
108+
*/
109+
_delayComputed: Ember.computed('delay', 'delayHide', 'delayShow', function () {
110+
const delayObject = {
111+
hide: this.get('delay'),
112+
show: this.get('delay')
113+
};
114+
115+
if (Ember.isPresent(this.get('delayHide'))) {
116+
Ember.set(delayObject, 'hide', this.get('delayHide'));
117+
}
118+
119+
if (Ember.isPresent(this.get('delayShow'))) {
120+
Ember.set(delayObject, 'show', this.get('delayShow'));
121+
}
122+
123+
return delayObject;
124+
})
93125
});

tests/dummy/app/templates/components/popover-demo/other-popover-options.hbs

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@
7676
</div>
7777

7878
<h4><code>content</code> (block)</h4>
79+
<div class="alert alert-info">
80+
<p>
81+
<i class="fa fa-info-circle"></i>
82+
Content specified in the nested block is automatically treated as html
83+
(you do not have to set <code>html?=true</code>).
84+
</p>
85+
</div>
86+
7987
<div class="row">
8088
<div class="col-sm-4 form-group">
8189
{{#twbs-popover as |popover|}}
@@ -87,6 +95,7 @@
8795
{{/popover.content}}
8896
{{/twbs-popover}}
8997
</div>
98+
9099
<div class="col-sm-8">
91100
{{!-- @formatter:off --}}
92101
<pre>\{{#twbs-popover as |popover|}}
@@ -105,7 +114,7 @@
105114
<h4><code>delay</code></h4>
106115
<div class="row">
107116
<div class="col-sm-4 form-group">
108-
{{#twbs-popover delay=1500 as |popover|}}
117+
{{#twbs-popover delay=500 as |popover|}}
109118
{{#popover.trigger}}
110119
<button class="btn btn-default">Click This Button</button>
111120
{{/popover.trigger}}
@@ -116,7 +125,7 @@
116125
</div>
117126
<div class="col-sm-8">
118127
{{!-- @formatter:off --}}
119-
<pre>\{{#twbs-popover delay=1500 as |popover|}}
128+
<pre>\{{#twbs-popover delay=500 as |popover|}}
120129
\{{#popover.trigger}}
121130
&lt;button class="btn btn-default">Click This Button&lt;/button>
122131
\{{/popover.trigger}}
@@ -129,48 +138,93 @@
129138
</div>
130139
</div>
131140

132-
<h4><code>html?=false</code> (DEFAULT)</h4>
141+
<h4><code>delayShow</code></h4>
133142
<div class="row">
134143
<div class="col-sm-4 form-group">
135-
{{#twbs-popover html?=false as |popover|}}
144+
{{#twbs-popover delayShow=500 as |popover|}}
136145
{{#popover.trigger}}
137146
<button class="btn btn-default">Click This Button</button>
138147
{{/popover.trigger}}
139148
{{#popover.content}}
140-
<p>This is treated as plain-text.</p>
149+
Click again to hide.
141150
{{/popover.content}}
142151
{{/twbs-popover}}
143152
</div>
144153
<div class="col-sm-8">
145154
{{!-- @formatter:off --}}
146-
<pre>\{{#twbs-popover html?=false as |popover|}}
155+
<pre>\{{#twbs-popover delayShow=500 as |popover|}}
147156
\{{#popover.trigger}}
148157
&lt;button class="btn btn-default">Click This Button&lt;/button>
149158
\{{/popover.trigger}}
150159
\{{#popover.content}}
151-
&lt;p>This is treated as plain-text.&lt;/p>
160+
Click again to hide.
152161
\{{/popover.content}}
153162
\{{/twbs-popover}}
154163
</pre>
155164
{{!-- @formatter:on --}}
156165
</div>
157166
</div>
158167

159-
<h4><code>html?=true</code></h4>
168+
<h4><code>delayHide</code></h4>
160169
<div class="row">
161170
<div class="col-sm-4 form-group">
162-
{{#twbs-popover html?=true as |popover|}}
171+
{{#twbs-popover delayHide=500 as |popover|}}
163172
{{#popover.trigger}}
164173
<button class="btn btn-default">Click This Button</button>
165174
{{/popover.trigger}}
166175
{{#popover.content}}
167-
<p>This is treated as <strong>html</strong>.</p>
176+
Click again to hide.
168177
{{/popover.content}}
169178
{{/twbs-popover}}
170179
</div>
171180
<div class="col-sm-8">
172181
{{!-- @formatter:off --}}
173-
<pre>\{{#twbs-popover html?=true as |popover|}}
182+
<pre>\{{#twbs-popover delayHide=500 as |popover|}}
183+
\{{#popover.trigger}}
184+
&lt;button class="btn btn-default">Click This Button&lt;/button>
185+
\{{/popover.trigger}}
186+
\{{#popover.content}}
187+
Click again to hide.
188+
\{{/popover.content}}
189+
\{{/twbs-popover}}
190+
</pre>
191+
{{!-- @formatter:on --}}
192+
</div>
193+
</div>
194+
195+
<h4><code>html?=false</code> (DEFAULT)</h4>
196+
<div class="row">
197+
<div class="col-sm-4 form-group">
198+
{{#twbs-popover html?=false content="<p>This is treated as plain-text.</p>" as |popover|}}
199+
{{#popover.trigger}}
200+
<button class="btn btn-default">Click This Button</button>
201+
{{/popover.trigger}}
202+
{{/twbs-popover}}
203+
</div>
204+
<div class="col-sm-8">
205+
{{!-- @formatter:off --}}
206+
<pre>\{{#twbs-popover html?=false content="&lt;p>This is treated as plain-text.&lt;/p>" as |popover|}}
207+
\{{#popover.trigger}}
208+
&lt;button class="btn btn-default">Click This Button&lt;/button>
209+
\{{/popover.trigger}}
210+
\{{/twbs-popover}}
211+
</pre>
212+
{{!-- @formatter:on --}}
213+
</div>
214+
</div>
215+
216+
<h4><code>html?=true</code></h4>
217+
<div class="row">
218+
<div class="col-sm-4 form-group">
219+
{{#twbs-popover html?=true content="<p>This is treated as <strong>HTML</strong>.</p>" as |popover|}}
220+
{{#popover.trigger}}
221+
<button class="btn btn-default">Click This Button</button>
222+
{{/popover.trigger}}
223+
{{/twbs-popover}}
224+
</div>
225+
<div class="col-sm-8">
226+
{{!-- @formatter:off --}}
227+
<pre>\{{#twbs-popover html?=true content="&lt;p>This is treated as &lt;strong>HTML&lt;/strong>.&lt;/p>" as |popover|}}
174228
\{{#popover.trigger}}
175229
&lt;button class="btn btn-default">Click This Button&lt;/button>
176230
\{{/popover.trigger}}
@@ -318,6 +372,14 @@
318372
</div>
319373

320374
<h4><code>title</code> (block)</h4>
375+
<div class="alert alert-info">
376+
<p>
377+
<i class="fa fa-info-circle"></i>
378+
A Title specified in the nested block is automatically treated as html
379+
(you do not have to set <code>html?=true</code>).
380+
</p>
381+
</div>
382+
321383
<div class="row">
322384
<div class="col-sm-4 form-group">
323385
{{#twbs-popover as |popover|}}

tests/dummy/app/templates/components/popover-demo/plain-or-html.hbs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
<h3>HTML-Based Popover Content</h3>
22

3+
<div class="alert alert-warning">
4+
<p>
5+
Keep in mind that when you use either the <code>twbs-popover/content</code> or <code>twbs-popover/title</code>
6+
components, the generated popover will be treated as html content.
7+
</p>
8+
</div>
9+
310
<div class="row">
411
<div class="col-sm-4 form-group">
5-
{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
12+
{{#twbs-popover popoverTrigger="click" as |popover|}}
613
{{#popover.trigger}}
714
<button class="btn btn-default">Click This Button</button>
815
{{/popover.trigger}}
@@ -18,7 +25,7 @@
1825
</div>
1926
<div class="col-sm-8">
2027
{{!-- @formatter:off --}}
21-
<pre>\{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
28+
<pre>\{{#twbs-popover popoverTrigger="click" as |popover|}}
2229
\{{#popover.trigger}}
2330
&lt;button class="btn btn-default">Click This Button&lt;/button>
2431
\{{/popover.trigger}}
@@ -40,7 +47,7 @@
4047

4148
<div class="row">
4249
<div class="col-sm-4 form-group">
43-
{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
50+
{{#twbs-popover popoverTrigger="click" as |popover|}}
4451
{{#popover.trigger}}
4552
<button class="btn btn-default">Click This Button</button>
4653
{{/popover.trigger}}
@@ -55,7 +62,7 @@
5562
</div>
5663
<div class="col-sm-8">
5764
{{!-- @formatter:off --}}
58-
<pre>\{{#twbs-popover popoverTrigger="click" html?=true as |popover|}}
65+
<pre>\{{#twbs-popover popoverTrigger="click" as |popover|}}
5966
\{{#popover.trigger}}
6067
&lt;button class="btn btn-default">Click This Button&lt;/button>
6168
\{{/popover.trigger}}
@@ -76,7 +83,7 @@
7683

7784
<div class="row">
7885
<div class="col-sm-4 form-group">
79-
{{#twbs-popover html?=true as |popover|}}
86+
{{#twbs-popover as |popover|}}
8087
{{#popover.trigger}}
8188
<button class="btn btn-default">Click this button</button>
8289
{{/popover.trigger}}
@@ -90,7 +97,7 @@
9097
</div>
9198
<div class="col-sm-8">
9299
{{!-- @formatter:off --}}
93-
<pre>\{{#twbs-popover html?=true as |popover|}}
100+
<pre>\{{#twbs-popover as |popover|}}
94101
\{{#popover.trigger}}
95102
&lt;button class="btn btn-default">Click this button&lt;/button>
96103
\{{/popover.trigger}}
@@ -110,7 +117,7 @@
110117

111118
<div class="row">
112119
<div class="col-sm-4 form-group">
113-
{{#twbs-popover html?=true as |popover|}}
120+
{{#twbs-popover as |popover|}}
114121
{{#popover.trigger}}
115122
<button class="btn btn-default">Click this button</button>
116123
{{/popover.trigger}}
@@ -124,7 +131,7 @@
124131
</div>
125132
<div class="col-sm-8">
126133
{{!-- @formatter:off --}}
127-
<pre>\{{#twbs-popover html?=true as |popover|}}
134+
<pre>\{{#twbs-popover as |popover|}}
128135
\{{#popover.trigger}}
129136
&lt;button class="btn btn-default">Click this button&lt;/button>
130137
\{{/popover.trigger}}

tests/dummy/app/templates/components/popover-demo/triggering-methods.hbs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
<li>
5757
The <code>hide</code>, <code>show</code>, and <code>toggle</code> actions (analogous to the
5858
<a href="http://getbootstrap.com/javascript/#popovers-methods" target="_blank">Bootstrap popover methods</a>) of
59-
the <code>\{{twbs-popover}}</code> will be available when you add them to the <em>as</em>.
59+
the <code>\{{twbs-popover}}</code> will be available when you add them to the
60+
<code>\{{#twbs-popover ...}}</code> <em>as</em>.
6061
</li>
6162
<li>
6263
When using these actions the <code>popoverTrigger</code> should be set to <code>manual</code> for these actions
@@ -116,7 +117,7 @@
116117
The <code>onShow</code>, <code>onShown</code>, <code>onHide</code>, <code>onHidden</code>, and
117118
<code>onInserted</code> events (analogous to the
118119
<a href="http://getbootstrap.com/javascript/#popovers-events" target="_blank">Bootstrap popover events</a>) of
119-
the <code>\{{twbs-popover}}</code> can be hooked into your component's, controller's, or route's actions. In
120+
the <code>\{{twbs-popover}}</code> can be hooked into your component's, controller's, or route's actions. In
120121
this example I have the <code>onShow</code>, <code>onShown</code>, etc. properties set to actions (of the
121122
exact same name) in my component that is responsible for rendering the <code>\{{twbs-popover}}</code>.
122123
</li>

tests/unit/mixins/popover-test.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ test('when requesting the options hash the defaults are all present', function (
1010
const options = popover.getOptions();
1111
assert.equal(options.animation, true);
1212
assert.equal(options.content, '');
13-
assert.equal(options.delay, 0);
13+
assert.equal(options.delay.hide, 0);
14+
assert.equal(options.delay.show, 0);
1415
assert.equal(options.html, false);
1516
assert.equal(options.placement, 'right');
1617
assert.equal(options.container, false);
@@ -34,9 +35,20 @@ test('when requesting the options hash the the popoverTrigger shows up under tri
3435
assert.equal(options.trigger, 'focus');
3536
});
3637

37-
// Replace this with your real tests.
38-
test('it works', function (assert) {
39-
let PopoverObject = Ember.Object.extend(PopoverMixin);
40-
let subject = PopoverObject.create();
41-
assert.ok(subject);
38+
test('when the delay value is set both show and hide are the same', function (assert) {
39+
const popoverMixin = Ember.Object.extend(PopoverMixin).create({delay: 500});
40+
assert.equal(popoverMixin.get('_delayComputed.hide'), 500);
41+
assert.equal(popoverMixin.get('_delayComputed.show'), 500);
42+
});
43+
44+
test('when only the delay-show value is set ', function (assert) {
45+
const popoverMixin = Ember.Object.extend(PopoverMixin).create({delayShow: 500});
46+
assert.equal(popoverMixin.get('_delayComputed.hide'), 0);
47+
assert.equal(popoverMixin.get('_delayComputed.show'), 500);
48+
});
49+
50+
test('when only the delay-hide value is set ', function (assert) {
51+
const popoverMixin = Ember.Object.extend(PopoverMixin).create({delayHide: 500});
52+
assert.equal(popoverMixin.get('_delayComputed.hide'), 500);
53+
assert.equal(popoverMixin.get('_delayComputed.show'), 0);
4254
});

0 commit comments

Comments
 (0)