coupdoeil 1.0.0.pre.alpha.9 → 1.0.0.pre.alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/coupdoeil.js +71 -47
- data/app/assets/javascripts/coupdoeil.min.js +1 -1
- data/app/assets/javascripts/coupdoeil.min.js.map +1 -1
- data/app/javascript/coupdoeil/elements/coupdoeil_element.js +15 -3
- data/app/javascript/coupdoeil/events/onclick.js +6 -6
- data/app/javascript/coupdoeil/events/onmouseover.js +8 -8
- data/app/javascript/coupdoeil/hovercard/closing.js +17 -2
- data/app/javascript/coupdoeil/hovercard/config.js +11 -11
- data/app/javascript/coupdoeil/hovercard/opening.js +11 -14
- data/app/javascript/coupdoeil/hovercard/optionsParser.js +22 -14
- data/app/models/coupdoeil/hovercard/option/opening_delay.rb +19 -0
- data/app/models/coupdoeil/hovercard/options_set.rb +1 -0
- data/app/models/coupdoeil/hovercard/view_context_delegation.rb +2 -1
- data/app/models/coupdoeil/hovercard.rb +3 -1
- data/lib/coupdoeil/version.rb +1 -1
- metadata +31 -2
@@ -17,17 +17,29 @@ export default class extends HTMLElement {
|
|
17
17
|
this.hovercardController = new HovercardController(this)
|
18
18
|
}
|
19
19
|
|
20
|
-
openHovercard() {
|
21
|
-
if (this.openingHovercard || this.hovercardController.isOpen) return;
|
20
|
+
openHovercard(triggerElement = null, callbacks) {
|
21
|
+
if (this.openingHovercard || this.hovercardController.isOpen || this.disabled || triggerElement === this) return;
|
22
22
|
|
23
23
|
this.openingHovercard = true
|
24
24
|
|
25
25
|
const parent = this.closest(HOVERCARD_SELECTOR)?.controller
|
26
26
|
addToCurrents(this)
|
27
|
-
return openHovercard(this.hovercardController, { parent })
|
27
|
+
return openHovercard(this.hovercardController, { parent, ...callbacks })
|
28
28
|
}
|
29
29
|
|
30
30
|
closeHovercard() {
|
31
31
|
closeNow(this.hovercardController)
|
32
32
|
}
|
33
|
+
|
34
|
+
get disabled() {
|
35
|
+
return !!this.getAttribute("disabled")
|
36
|
+
}
|
37
|
+
|
38
|
+
set disabled(disabled) {
|
39
|
+
if (disabled) {
|
40
|
+
this.setAttribute("disabled", true)
|
41
|
+
} else {
|
42
|
+
this.removeAttribute("disabled")
|
43
|
+
}
|
44
|
+
}
|
33
45
|
}
|
@@ -8,10 +8,10 @@ export const coupdoeilOnClickEvent = ({ target: clickedElement }) => {
|
|
8
8
|
const hovercardElement = clickedElement.closest(HOVERCARD_SELECTOR)
|
9
9
|
|
10
10
|
if (coupdoeilElement && hovercardElement) {
|
11
|
-
handleClickedCoupdoeilWithinHovercard(coupdoeilElement, hovercardElement)
|
11
|
+
handleClickedCoupdoeilWithinHovercard(coupdoeilElement, hovercardElement, clickedElement)
|
12
12
|
}
|
13
13
|
else if (coupdoeilElement) {
|
14
|
-
handleClickedCoupdoeilOutsideHovercard(coupdoeilElement)
|
14
|
+
handleClickedCoupdoeilOutsideHovercard(coupdoeilElement, clickedElement)
|
15
15
|
}
|
16
16
|
else if (hovercardElement) {
|
17
17
|
handleClickOutsideCoupdoeilButWithinHovercard(hovercardElement, clickedElement)
|
@@ -21,7 +21,7 @@ export const coupdoeilOnClickEvent = ({ target: clickedElement }) => {
|
|
21
21
|
}
|
22
22
|
}
|
23
23
|
|
24
|
-
function handleClickedCoupdoeilWithinHovercard(coupdoeilElement, _hovercardElement) {
|
24
|
+
function handleClickedCoupdoeilWithinHovercard(coupdoeilElement, _hovercardElement, clickedElement) {
|
25
25
|
const hovercard = coupdoeilElement.hovercardController
|
26
26
|
if(noTriggeredOnClick(hovercard))
|
27
27
|
return;
|
@@ -32,11 +32,11 @@ function handleClickedCoupdoeilWithinHovercard(coupdoeilElement, _hovercardEleme
|
|
32
32
|
} else {
|
33
33
|
// first click on a closed hovercard trigger opens it
|
34
34
|
// If any other hovercard is open, it is the parent hovercard, hence it should not be closed.
|
35
|
-
coupdoeilElement.openHovercard()
|
35
|
+
coupdoeilElement.openHovercard(clickedElement)
|
36
36
|
}
|
37
37
|
}
|
38
38
|
|
39
|
-
function handleClickedCoupdoeilOutsideHovercard(coupdoeilElement) {
|
39
|
+
function handleClickedCoupdoeilOutsideHovercard(coupdoeilElement, clickedElement) {
|
40
40
|
const hovercard = coupdoeilElement.hovercardController
|
41
41
|
if(noTriggeredOnClick(hovercard))
|
42
42
|
return;
|
@@ -48,7 +48,7 @@ function handleClickedCoupdoeilOutsideHovercard(coupdoeilElement) {
|
|
48
48
|
// close any other open hovercard
|
49
49
|
closeAllNow()
|
50
50
|
// first click on a closed hovercard trigger opens it
|
51
|
-
coupdoeilElement.openHovercard()
|
51
|
+
coupdoeilElement.openHovercard(clickedElement)
|
52
52
|
}
|
53
53
|
}
|
54
54
|
|
@@ -5,7 +5,8 @@ import {
|
|
5
5
|
cancelCloseRequest,
|
6
6
|
closeChildrenNow,
|
7
7
|
closeOnHoverChildrenLater,
|
8
|
-
closeTriggeredOnHoverLater,
|
8
|
+
closeTriggeredOnHoverLater,
|
9
|
+
closeTriggeredOnHoverNowUnlessAncestor
|
9
10
|
} from "../hovercard/closing";
|
10
11
|
import {addToCurrents as addToCurrentHovercards} from "../hovercard/current";
|
11
12
|
|
@@ -14,10 +15,10 @@ export const onMouseOver = ({ target: hoveredElement }) => {
|
|
14
15
|
const hovercardElement = hoveredElement.closest(HOVERCARD_SELECTOR)
|
15
16
|
|
16
17
|
if (coupdoeilElement && hovercardElement) {
|
17
|
-
handleMouseOverCoupdoeilWithinHovercard(coupdoeilElement, hovercardElement)
|
18
|
+
handleMouseOverCoupdoeilWithinHovercard(coupdoeilElement, hovercardElement, hoveredElement)
|
18
19
|
}
|
19
20
|
else if (coupdoeilElement) {
|
20
|
-
handleMouseOverCoupdoeilOutsideHovercard(coupdoeilElement)
|
21
|
+
handleMouseOverCoupdoeilOutsideHovercard(coupdoeilElement, hoveredElement)
|
21
22
|
}
|
22
23
|
else if (hovercardElement) {
|
23
24
|
handleOverOutsideCoupdoeilButWithinHovercard(hovercardElement)
|
@@ -27,7 +28,7 @@ export const onMouseOver = ({ target: hoveredElement }) => {
|
|
27
28
|
}
|
28
29
|
}
|
29
30
|
|
30
|
-
function handleMouseOverCoupdoeilWithinHovercard(coupdoeilElement, hovercardElement) {
|
31
|
+
function handleMouseOverCoupdoeilWithinHovercard(coupdoeilElement, hovercardElement, hoveredElement) {
|
31
32
|
const childHovercard = coupdoeilElement.hovercardController
|
32
33
|
const parentHovercard = hovercardElement.controller
|
33
34
|
if(notTriggeredOnHover(childHovercard))
|
@@ -41,19 +42,18 @@ function handleMouseOverCoupdoeilWithinHovercard(coupdoeilElement, hovercardElem
|
|
41
42
|
// ensures to close other children hovercards before opening the one that current one
|
42
43
|
closeChildrenNow(parentHovercard)
|
43
44
|
// should also close any open hovercard outside of parent
|
44
|
-
coupdoeilElement.openHovercard()
|
45
|
+
coupdoeilElement.openHovercard(hoveredElement)
|
45
46
|
}
|
46
47
|
}
|
47
48
|
|
48
|
-
function handleMouseOverCoupdoeilOutsideHovercard(coupdoeilElement) {
|
49
|
+
function handleMouseOverCoupdoeilOutsideHovercard(coupdoeilElement, hoveredElement) {
|
49
50
|
const hovercard = coupdoeilElement.hovercardController
|
50
51
|
if(notTriggeredOnHover(hovercard))
|
51
52
|
return;
|
52
53
|
|
53
54
|
if (hovercard.isClosed) {
|
54
55
|
// Close any other open hovercard before opening this one
|
55
|
-
|
56
|
-
coupdoeilElement.openHovercard()
|
56
|
+
coupdoeilElement.openHovercard(hoveredElement, { beforeDisplay: closeTriggeredOnHoverNowUnlessAncestor })
|
57
57
|
} else if (hovercard.closingRequest) {
|
58
58
|
// hovercard is still open but was requested to close, then it clear this closing request
|
59
59
|
// and ensures the hovercards stays in current hovercards register
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import {triggeredOnHover} from "./attributes"
|
2
|
-
import {
|
2
|
+
import {CLOSING_DELAY_MS} from "./config"
|
3
3
|
import {leave} from "el-transition"
|
4
4
|
import {addToCurrents, CURRENT_HOVERCARDS_BY_ID, removeFromCurrents} from "./current"
|
5
5
|
|
@@ -68,7 +68,7 @@ export function closeLater(controller) {
|
|
68
68
|
cancelOpenCloseActions(controller)
|
69
69
|
controller.closingRequest = setTimeout(() => {
|
70
70
|
closeNow(controller)
|
71
|
-
},
|
71
|
+
}, CLOSING_DELAY_MS)
|
72
72
|
}
|
73
73
|
|
74
74
|
export function closeChildrenNow(controller) {
|
@@ -123,3 +123,18 @@ export function closeTriggeredOnHoverLater() {
|
|
123
123
|
}
|
124
124
|
}
|
125
125
|
}
|
126
|
+
|
127
|
+
export function closeTriggeredOnHoverNowUnlessAncestor(controller) {
|
128
|
+
let topMostParent = controller
|
129
|
+
while (topMostParent.parent) {
|
130
|
+
topMostParent = topMostParent.parent
|
131
|
+
}
|
132
|
+
const idToSkip = topMostParent.coupdoeilElement.uniqueId
|
133
|
+
|
134
|
+
for (const coupdoeilElement of CURRENT_HOVERCARDS_BY_ID.values()) {
|
135
|
+
if (coupdoeilElement.uniqueId !== idToSkip && triggeredOnHover(coupdoeilElement.hovercardController)) {
|
136
|
+
closeNow(coupdoeilElement.hovercardController)
|
137
|
+
removeFromCurrents(coupdoeilElement)
|
138
|
+
}
|
139
|
+
}
|
140
|
+
}
|
@@ -2,14 +2,14 @@ export const HOVERCARD_CLASS_NAME = 'coupdoeil--hovercard'
|
|
2
2
|
export const HOVERCARD_SELECTOR = `.${HOVERCARD_CLASS_NAME}`
|
3
3
|
export const HOVERCARD_CLOSE_BTN_SELECTOR = '[data-hovercard-close]'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
// the time (ms) to wait before closing the hovercard,
|
6
|
+
// to avoid flickering if the user hovers out and in quickly,
|
7
|
+
// or if the user moves the mouse from the target to the hovercard
|
8
|
+
export const CLOSING_DELAY_MS = 75
|
9
|
+
|
10
|
+
// the time (ms) to wait before starting to fetch the content,
|
11
|
+
// to avoid fetching too soon if the user hovers in and out the target quickly
|
12
|
+
export const FETCH_DELAY_MS = 100
|
13
|
+
|
14
|
+
// the minimum time (ms) the user should wait before seeing the hovercard
|
15
|
+
export const OPENING_DELAY_MS = 200
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import {FETCH_DELAY_MS, HOVERCARD_CLASS_NAME, OPENING_DELAY_MS} from "./config"
|
2
2
|
import {getParams, getType, preloadedContentElement, triggeredOnClick} from "./attributes"
|
3
3
|
import {getHovercardContentHTML, setHovercardContentHTML} from "./cache"
|
4
4
|
import {extractOptionsFromElement} from "./optionsParser"
|
@@ -47,7 +47,7 @@ async function loadHovercardContentHTML(controller, options, delayOptions) {
|
|
47
47
|
})
|
48
48
|
}
|
49
49
|
|
50
|
-
export async function openHovercard(controller, { parent }) {
|
50
|
+
export async function openHovercard(controller, { parent, beforeDisplay }) {
|
51
51
|
if (controller.isOpen) {
|
52
52
|
return cancelCloseRequest(controller)
|
53
53
|
}
|
@@ -56,8 +56,8 @@ export async function openHovercard(controller, { parent }) {
|
|
56
56
|
parent.children.add(controller)
|
57
57
|
}
|
58
58
|
|
59
|
-
const delays = getDelayOptionsForController(controller)
|
60
59
|
const options = extractOptionsFromElement(controller.coupdoeilElement)
|
60
|
+
const delays = getDelayOptionsForController(controller, options)
|
61
61
|
|
62
62
|
const openingDelay = new Promise(resolve => setTimeout(resolve, delays.opening))
|
63
63
|
const fetchDelay = loadHovercardContentHTML(controller, options, delays)
|
@@ -67,11 +67,11 @@ export async function openHovercard(controller, { parent }) {
|
|
67
67
|
|
68
68
|
// but if opening has been canceled (nullified), the wait still happens, so we need to check again
|
69
69
|
if (controller.coupdoeilElement.openingHovercard && !parentIsClosedOrClosing) {
|
70
|
-
await display(controller, options)
|
70
|
+
await display(controller, options, beforeDisplay)
|
71
71
|
}
|
72
72
|
}
|
73
73
|
|
74
|
-
async function display(controller, options) {
|
74
|
+
async function display(controller, options, beforeDisplay) {
|
75
75
|
if (controller.isOpen) return;
|
76
76
|
|
77
77
|
cancelCloseRequest(controller)
|
@@ -91,6 +91,9 @@ async function display(controller, options) {
|
|
91
91
|
controller.card.style.removeProperty('visibility')
|
92
92
|
|
93
93
|
executeNextFrameIfStillOpening(controller, async () => {
|
94
|
+
if (beforeDisplay) {
|
95
|
+
beforeDisplay(controller)
|
96
|
+
}
|
94
97
|
// // adding again the card to make sure it is in the map, could be better
|
95
98
|
addToCurrents(controller.coupdoeilElement)
|
96
99
|
delete controller.coupdoeilElement.openingHovercard
|
@@ -111,18 +114,12 @@ function executeNextFrameIfStillOpening(controller, callback) {
|
|
111
114
|
})
|
112
115
|
}
|
113
116
|
|
114
|
-
function getDelayOptionsForController(controller) {
|
115
|
-
if (triggeredOnClick(controller)) {
|
117
|
+
function getDelayOptionsForController(controller, options) {
|
118
|
+
if (options.openingDelay === false || triggeredOnClick(controller)) {
|
116
119
|
return { fetch: 0, opening: 0 }
|
117
120
|
}
|
118
121
|
|
119
|
-
|
120
|
-
if (defaultConfig.openingDelay === 0) {
|
121
|
-
fetchDelay = 0
|
122
|
-
} else {
|
123
|
-
fetchDelay = defaultConfig.openingDelay / 2
|
124
|
-
}
|
125
|
-
return { fetch: fetchDelay, opening: defaultConfig.openingDelay }
|
122
|
+
return { fetch: FETCH_DELAY_MS, opening: OPENING_DELAY_MS }
|
126
123
|
}
|
127
124
|
|
128
125
|
function buildHovercardElement(controller, options) {
|
@@ -1,19 +1,21 @@
|
|
1
1
|
const OPTIONS = {
|
2
2
|
animation: { getter: getAnimation },
|
3
3
|
cache: { getter: getCache },
|
4
|
+
loading: { getter: getLoading },
|
4
5
|
offset: { getter: getOffset },
|
6
|
+
openingDelay: { getter: getOpeningDelay },
|
5
7
|
placement: { getter: getPlacement },
|
6
|
-
|
7
|
-
trigger: { getter: getTrigger }
|
8
|
+
trigger: { getter: getTrigger },
|
8
9
|
}
|
9
10
|
|
10
11
|
const ORDERED_OPTIONS = [
|
11
|
-
"trigger",
|
12
|
-
"loading",
|
13
|
-
"cache",
|
14
|
-
"
|
15
|
-
"
|
16
|
-
"
|
12
|
+
"trigger", // bit size: 1 shift: 0
|
13
|
+
"loading", // bit size: 2 shift: 1
|
14
|
+
"cache", // bit size: 1 shift: 3
|
15
|
+
"openingDelay", // bit size: 1 shift: 4
|
16
|
+
"animation", // bit size: 3 shift: 5
|
17
|
+
"placement", // bit size: 16 shift: 8
|
18
|
+
"offset" // bit size: 21 shift: 24
|
17
19
|
]
|
18
20
|
|
19
21
|
const TRIGGERS = ["hover", "click"]
|
@@ -39,8 +41,8 @@ function parseCSSSize(value) {
|
|
39
41
|
}
|
40
42
|
|
41
43
|
function getOffset(optionsInt) {
|
42
|
-
// shift is BigInt(16 + 3 + 1 + 2 + 1)
|
43
|
-
const offsetBits = Number(BigInt(optionsInt) >> BigInt(
|
44
|
+
// shift is BigInt(16 + 3 + 1 + 1 + 2 + 1)
|
45
|
+
const offsetBits = Number(BigInt(optionsInt) >> BigInt(24))
|
44
46
|
if (offsetBits === 0)
|
45
47
|
return 0
|
46
48
|
|
@@ -55,8 +57,8 @@ function getOffset(optionsInt) {
|
|
55
57
|
}
|
56
58
|
|
57
59
|
function getPlacement(optionsInt) {
|
58
|
-
// shift is 3 + 1 + 2 + 1, mask is 2 ** 16 - 1
|
59
|
-
const placementBits = (optionsInt >>
|
60
|
+
// shift is 3 + 1 + 1 + 2 + 1, mask is 2 ** 16 - 1
|
61
|
+
const placementBits = (optionsInt >> 8) & 65535
|
60
62
|
let shift = 0
|
61
63
|
let lastPlacement = null
|
62
64
|
const placements = []
|
@@ -70,7 +72,12 @@ function getPlacement(optionsInt) {
|
|
70
72
|
}
|
71
73
|
|
72
74
|
function getAnimation(optionsInt) {
|
73
|
-
return ANIMATIONS[(optionsInt & 56) >>
|
75
|
+
// return ANIMATIONS[(optionsInt & 56) >> 5]
|
76
|
+
return ANIMATIONS[(optionsInt >> 5) & 7]
|
77
|
+
}
|
78
|
+
|
79
|
+
function getOpeningDelay(optionsInt) {
|
80
|
+
return ((optionsInt >> 4) & 1) === 1
|
74
81
|
}
|
75
82
|
|
76
83
|
function getCache(optionsInt) {
|
@@ -89,9 +96,10 @@ function getTrigger(optionsInt) {
|
|
89
96
|
const HovercardOptions = {
|
90
97
|
animation: undefined,
|
91
98
|
cache: undefined,
|
99
|
+
loading: undefined,
|
92
100
|
offset: undefined,
|
101
|
+
openingDelay: undefined,
|
93
102
|
placement: undefined,
|
94
|
-
loading: undefined,
|
95
103
|
trigger: undefined,
|
96
104
|
}
|
97
105
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coupdoeil
|
4
|
+
class Hovercard
|
5
|
+
class Option
|
6
|
+
class OpeningDelay < Coupdoeil::Hovercard::Option
|
7
|
+
self.bit_size = 1
|
8
|
+
|
9
|
+
VALUES = [true, false].freeze
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def parse(value) = value ? 1 : 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate! = validate_inclusion!
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Coupdoeil
|
4
4
|
class Hovercard
|
5
5
|
module ViewContextDelegation
|
6
|
-
attr_accessor :__cp_view_context
|
6
|
+
attr_accessor :__cp_view_context, :hovercard
|
7
7
|
|
8
8
|
# For CSRF authenticity tokens in forms
|
9
9
|
def config = __cp_view_context.config
|
@@ -13,6 +13,7 @@ module Coupdoeil
|
|
13
13
|
|
14
14
|
def helpers = __cp_view_context
|
15
15
|
def controller = __cp_view_context.controller
|
16
|
+
def params = hovercard.params
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
@@ -34,7 +34,8 @@ module Coupdoeil
|
|
34
34
|
animation: "slide-in",
|
35
35
|
cache: true,
|
36
36
|
loading: :async,
|
37
|
-
trigger: "hover"
|
37
|
+
trigger: "hover",
|
38
|
+
opening_delay: true
|
38
39
|
)
|
39
40
|
|
40
41
|
DoubleRenderError = Class.new(::AbstractController::DoubleRenderError)
|
@@ -92,6 +93,7 @@ module Coupdoeil
|
|
92
93
|
def view_context
|
93
94
|
super.tap do |context|
|
94
95
|
context.extend ViewContextDelegation
|
96
|
+
context.hovercard = self
|
95
97
|
context.__cp_view_context = @__cp_view_context
|
96
98
|
end
|
97
99
|
end
|
data/lib/coupdoeil/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coupdoeil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.alpha.
|
4
|
+
version: 1.0.0.pre.alpha.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- PageHey
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-05-
|
10
|
+
date: 2025-05-27 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: actionpack
|
@@ -99,6 +99,34 @@ dependencies:
|
|
99
99
|
- - ">="
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: '0'
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: turbo-rails
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
type: :development
|
110
|
+
prerelease: false
|
111
|
+
version_requirements: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
- !ruby/object:Gem::Dependency
|
117
|
+
name: stimulus-rails
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
type: :development
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
102
130
|
description: Easy and powerful hovercard system for Ruby On Rails.
|
103
131
|
email:
|
104
132
|
- pagehey@pm.me
|
@@ -143,6 +171,7 @@ files:
|
|
143
171
|
- app/models/coupdoeil/hovercard/option/cache.rb
|
144
172
|
- app/models/coupdoeil/hovercard/option/loading.rb
|
145
173
|
- app/models/coupdoeil/hovercard/option/offset.rb
|
174
|
+
- app/models/coupdoeil/hovercard/option/opening_delay.rb
|
146
175
|
- app/models/coupdoeil/hovercard/option/placement.rb
|
147
176
|
- app/models/coupdoeil/hovercard/option/trigger.rb
|
148
177
|
- app/models/coupdoeil/hovercard/options_set.rb
|