coupdoeil 1.0.0.pre.beta.1 → 1.0.0.pre.beta.2
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/CHANGELOG.md +3 -0
- data/README.md +21 -21
- data/app/assets/javascripts/coupdoeil.js +132 -132
- data/app/assets/javascripts/coupdoeil.min.js +1 -1
- data/app/assets/javascripts/coupdoeil.min.js.map +1 -1
- data/app/assets/stylesheets/coupdoeil/popover-animation.css +44 -0
- data/app/assets/stylesheets/coupdoeil/popover-arrow.css +39 -0
- data/app/assets/stylesheets/coupdoeil/popover.css +84 -0
- data/app/controllers/coupdoeil/{hovercards_controller.rb → popovers_controller.rb} +13 -13
- data/app/helpers/coupdoeil/application_helper.rb +4 -4
- data/app/javascript/coupdoeil/elements/coupdoeil_element.js +13 -13
- data/app/javascript/coupdoeil/events/onclick.js +36 -36
- data/app/javascript/coupdoeil/events/onmouseover.js +52 -52
- data/app/javascript/coupdoeil/events.js +4 -4
- data/app/javascript/coupdoeil/index.js +1 -1
- data/app/javascript/coupdoeil/{hovercard → popover}/attributes.js +3 -3
- data/app/javascript/coupdoeil/popover/cache.js +22 -0
- data/app/javascript/coupdoeil/{hovercard → popover}/closing.js +18 -18
- data/app/javascript/coupdoeil/{hovercard → popover}/config.js +6 -6
- data/app/javascript/coupdoeil/popover/controller.js +20 -0
- data/app/javascript/coupdoeil/popover/current.js +13 -0
- data/app/javascript/coupdoeil/{hovercard → popover}/opening.js +26 -26
- data/app/javascript/coupdoeil/{hovercard → popover}/optionsParser.js +5 -5
- data/app/javascript/coupdoeil/{hovercard → popover}/positioning.js +2 -2
- data/app/javascript/coupdoeil/popover/state_check.js +12 -0
- data/app/models/coupdoeil/params.rb +4 -4
- data/app/models/coupdoeil/{hovercard → popover}/option/animation.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/option/cache.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/option/loading.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/option/offset.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/option/opening_delay.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/option/placement.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/option/trigger.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/option.rb +1 -1
- data/app/models/coupdoeil/{hovercard → popover}/options_set.rb +1 -1
- data/app/models/coupdoeil/{hovercard → popover}/registry.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/setup.rb +2 -2
- data/app/models/coupdoeil/{hovercard → popover}/view_context_delegation.rb +3 -3
- data/app/models/coupdoeil/{hovercard.rb → popover.rb} +8 -8
- data/app/models/coupdoeil/tag.rb +15 -15
- data/app/style/{hovercard-animation.scss → popover-animation.scss} +7 -7
- data/app/style/popover-arrow.scss +40 -0
- data/app/style/popover.scss +2 -0
- data/config/routes.rb +1 -1
- data/lib/coupdoeil/engine.rb +8 -8
- data/lib/coupdoeil/version.rb +1 -1
- data/lib/generators/coupdoeil/install/install_generator.rb +8 -8
- data/lib/generators/coupdoeil/install/templates/layout.html.erb.tt +1 -1
- data/lib/generators/coupdoeil/popover/USAGE +15 -0
- data/lib/generators/coupdoeil/popover/popover_generator.rb +22 -0
- data/lib/generators/coupdoeil/{hovercard/templates/hovercard.rb.tt → popover/templates/popover.rb.tt} +1 -1
- metadata +39 -39
- data/app/assets/stylesheets/coupdoeil/hovercard-animation.css +0 -44
- data/app/assets/stylesheets/coupdoeil/hovercard-arrow.css +0 -39
- data/app/assets/stylesheets/coupdoeil/hovercard.css +0 -84
- data/app/javascript/coupdoeil/hovercard/cache.js +0 -22
- data/app/javascript/coupdoeil/hovercard/controller.js +0 -20
- data/app/javascript/coupdoeil/hovercard/current.js +0 -13
- data/app/javascript/coupdoeil/hovercard/state_check.js +0 -12
- data/app/style/hovercard-arrow.scss +0 -40
- data/app/style/hovercard.scss +0 -2
- data/lib/generators/coupdoeil/hovercard/USAGE +0 -15
- data/lib/generators/coupdoeil/hovercard/hovercard_generator.rb +0 -22
- /data/app/javascript/coupdoeil/{hovercard → popover}/actions.js +0 -0
- /data/app/javascript/coupdoeil/{hovercard.js → popover.js} +0 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
.coupdoeil--popover.hidden {
|
2
|
+
display: none;
|
3
|
+
}
|
4
|
+
|
5
|
+
.coupdoeil--popover[data-animation].popover-enter {
|
6
|
+
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
7
|
+
}
|
8
|
+
.coupdoeil--popover[data-animation].popover-leave {
|
9
|
+
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
10
|
+
}
|
11
|
+
.coupdoeil--popover[data-animation].popover-enter, .coupdoeil--popover[data-animation].popover-leave {
|
12
|
+
transition-property: opacity, transform;
|
13
|
+
transition-duration: 150ms;
|
14
|
+
}
|
15
|
+
.coupdoeil--popover[data-animation].popover-enter-end[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-enter-end[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-enter-end[data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-start[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-leave-start[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-start[data-animation=slide-out] {
|
16
|
+
opacity: 1;
|
17
|
+
}
|
18
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-enter-start[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-enter-start[data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-leave-end[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-animation=slide-out] {
|
19
|
+
opacity: 0;
|
20
|
+
}
|
21
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=right][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=right][data-animation=slide-in] {
|
22
|
+
transform: translateX(1rem);
|
23
|
+
}
|
24
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=right][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=right][data-animation=slide-out] {
|
25
|
+
transform: translateX(-1rem);
|
26
|
+
}
|
27
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=left][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=left][data-animation=slide-in] {
|
28
|
+
transform: translateX(-1rem);
|
29
|
+
}
|
30
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=left][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=left][data-animation=slide-out] {
|
31
|
+
transform: translateX(1rem);
|
32
|
+
}
|
33
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=top][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=top][data-animation=slide-in] {
|
34
|
+
transform: translateY(-1rem);
|
35
|
+
}
|
36
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=top][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=top][data-animation=slide-out] {
|
37
|
+
transform: translateY(1rem);
|
38
|
+
}
|
39
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=bottom][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=bottom][data-animation=slide-in] {
|
40
|
+
transform: translateY(1rem);
|
41
|
+
}
|
42
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=bottom][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=bottom][data-animation=slide-out] {
|
43
|
+
transform: translateY(-1rem);
|
44
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
.coupdoeil--popover [data-popover-arrow] {
|
2
|
+
--co-popover--color: white;
|
3
|
+
--co-popover--border-color: rgb(209 213 219);
|
4
|
+
--co-popover-border-size: 1px;
|
5
|
+
--co-popover-border-style: solid;
|
6
|
+
--co-popover--size-ratio: 1;
|
7
|
+
--co-popover--height: 0.75rem;
|
8
|
+
--co-popover--width: calc(var(--co-popover--height) / var(--co-popover--size-ratio));
|
9
|
+
position: absolute;
|
10
|
+
height: var(--co-popover--height);
|
11
|
+
width: var(--co-popover--height);
|
12
|
+
}
|
13
|
+
.coupdoeil--popover [data-popover-arrow]::after, .coupdoeil--popover [data-popover-arrow]::before {
|
14
|
+
content: "";
|
15
|
+
width: 0;
|
16
|
+
height: 0;
|
17
|
+
position: absolute;
|
18
|
+
bottom: 0;
|
19
|
+
border: var(--co-popover--base-border-width) var(--co-popover-border-style) transparent;
|
20
|
+
}
|
21
|
+
.coupdoeil--popover [data-popover-arrow]::after {
|
22
|
+
--co-popover--base-border-width: var(--co-popover--width);
|
23
|
+
border-bottom-color: var(--co-popover--color);
|
24
|
+
left: calc(50% - var(--co-popover--width));
|
25
|
+
}
|
26
|
+
.coupdoeil--popover [data-popover-arrow]::before {
|
27
|
+
--co-popover--base-border-width: calc(var(--co-popover--height) + var(--co-popover-border-size));
|
28
|
+
border-bottom-color: var(--co-popover--border-color);
|
29
|
+
left: calc(50% - var(--co-popover--width) - var(--co-popover-border-size));
|
30
|
+
}
|
31
|
+
.coupdoeil--popover[data-placement|=top] [data-popover-arrow] {
|
32
|
+
transform: rotate(180deg);
|
33
|
+
}
|
34
|
+
.coupdoeil--popover[data-placement|=right] [data-popover-arrow] {
|
35
|
+
transform: rotate(-90deg);
|
36
|
+
}
|
37
|
+
.coupdoeil--popover[data-placement|=left] [data-popover-arrow] {
|
38
|
+
transform: rotate(90deg);
|
39
|
+
}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
.coupdoeil--popover.hidden {
|
2
|
+
display: none;
|
3
|
+
}
|
4
|
+
|
5
|
+
.coupdoeil--popover[data-animation].popover-enter {
|
6
|
+
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
7
|
+
}
|
8
|
+
.coupdoeil--popover[data-animation].popover-leave {
|
9
|
+
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
10
|
+
}
|
11
|
+
.coupdoeil--popover[data-animation].popover-enter, .coupdoeil--popover[data-animation].popover-leave {
|
12
|
+
transition-property: opacity, transform;
|
13
|
+
transition-duration: 150ms;
|
14
|
+
}
|
15
|
+
.coupdoeil--popover[data-animation].popover-enter-end[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-enter-end[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-enter-end[data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-start[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-leave-start[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-start[data-animation=slide-out] {
|
16
|
+
opacity: 1;
|
17
|
+
}
|
18
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-enter-start[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-enter-start[data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-animation=fade-in], .coupdoeil--popover[data-animation].popover-leave-end[data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-animation=slide-out] {
|
19
|
+
opacity: 0;
|
20
|
+
}
|
21
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=right][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=right][data-animation=slide-in] {
|
22
|
+
transform: translateX(1rem);
|
23
|
+
}
|
24
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=right][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=right][data-animation=slide-out] {
|
25
|
+
transform: translateX(-1rem);
|
26
|
+
}
|
27
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=left][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=left][data-animation=slide-in] {
|
28
|
+
transform: translateX(-1rem);
|
29
|
+
}
|
30
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=left][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=left][data-animation=slide-out] {
|
31
|
+
transform: translateX(1rem);
|
32
|
+
}
|
33
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=top][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=top][data-animation=slide-in] {
|
34
|
+
transform: translateY(-1rem);
|
35
|
+
}
|
36
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=top][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=top][data-animation=slide-out] {
|
37
|
+
transform: translateY(1rem);
|
38
|
+
}
|
39
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=bottom][data-animation=slide-in], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=bottom][data-animation=slide-in] {
|
40
|
+
transform: translateY(1rem);
|
41
|
+
}
|
42
|
+
.coupdoeil--popover[data-animation].popover-enter-start[data-placement|=bottom][data-animation=slide-out], .coupdoeil--popover[data-animation].popover-leave-end[data-placement|=bottom][data-animation=slide-out] {
|
43
|
+
transform: translateY(-1rem);
|
44
|
+
}
|
45
|
+
|
46
|
+
.coupdoeil--popover [data-popover-arrow] {
|
47
|
+
--co-popover--color: white;
|
48
|
+
--co-popover--border-color: rgb(209 213 219);
|
49
|
+
--co-popover-border-size: 1px;
|
50
|
+
--co-popover-border-style: solid;
|
51
|
+
--co-popover--size-ratio: 1;
|
52
|
+
--co-popover--height: 0.75rem;
|
53
|
+
--co-popover--width: calc(var(--co-popover--height) / var(--co-popover--size-ratio));
|
54
|
+
position: absolute;
|
55
|
+
height: var(--co-popover--height);
|
56
|
+
width: var(--co-popover--height);
|
57
|
+
}
|
58
|
+
.coupdoeil--popover [data-popover-arrow]::after, .coupdoeil--popover [data-popover-arrow]::before {
|
59
|
+
content: "";
|
60
|
+
width: 0;
|
61
|
+
height: 0;
|
62
|
+
position: absolute;
|
63
|
+
bottom: 0;
|
64
|
+
border: var(--co-popover--base-border-width) var(--co-popover-border-style) transparent;
|
65
|
+
}
|
66
|
+
.coupdoeil--popover [data-popover-arrow]::after {
|
67
|
+
--co-popover--base-border-width: var(--co-popover--width);
|
68
|
+
border-bottom-color: var(--co-popover--color);
|
69
|
+
left: calc(50% - var(--co-popover--width));
|
70
|
+
}
|
71
|
+
.coupdoeil--popover [data-popover-arrow]::before {
|
72
|
+
--co-popover--base-border-width: calc(var(--co-popover--height) + var(--co-popover-border-size));
|
73
|
+
border-bottom-color: var(--co-popover--border-color);
|
74
|
+
left: calc(50% - var(--co-popover--width) - var(--co-popover-border-size));
|
75
|
+
}
|
76
|
+
.coupdoeil--popover[data-placement|=top] [data-popover-arrow] {
|
77
|
+
transform: rotate(180deg);
|
78
|
+
}
|
79
|
+
.coupdoeil--popover[data-placement|=right] [data-popover-arrow] {
|
80
|
+
transform: rotate(-90deg);
|
81
|
+
}
|
82
|
+
.coupdoeil--popover[data-placement|=left] [data-popover-arrow] {
|
83
|
+
transform: rotate(90deg);
|
84
|
+
}
|
@@ -1,19 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Coupdoeil
|
4
|
-
class
|
4
|
+
class PopoversController < ApplicationController
|
5
5
|
before_action :set_action_and_resource_name
|
6
|
-
before_action :
|
7
|
-
before_action :
|
6
|
+
before_action :set_popover_class
|
7
|
+
before_action :set_popover_params
|
8
8
|
|
9
|
-
filters = _process_action_callbacks.map(&:filter) - %i[set_action_and_resource_name
|
9
|
+
filters = _process_action_callbacks.map(&:filter) - %i[set_action_and_resource_name set_popover_class set_popover_params]
|
10
10
|
skip_before_action(*filters, raise: false)
|
11
11
|
skip_after_action(*filters, raise: false)
|
12
12
|
skip_around_action(*filters, raise: false)
|
13
13
|
|
14
14
|
def create
|
15
|
-
|
16
|
-
render plain:
|
15
|
+
popover = @popover_klass.new(@popover_params, view_context)
|
16
|
+
render plain: popover.process(@action_name), layout: false
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
@@ -23,19 +23,19 @@ module Coupdoeil
|
|
23
23
|
end
|
24
24
|
|
25
25
|
if Rails.env.development?
|
26
|
-
def
|
27
|
-
@
|
26
|
+
def set_popover_class
|
27
|
+
@popover_klass = Coupdoeil::Popover.registry.lookup_or_register(@resource_name)
|
28
28
|
end
|
29
29
|
else
|
30
|
-
def
|
31
|
-
@
|
30
|
+
def set_popover_class
|
31
|
+
@popover_klass = Coupdoeil::Popover.registry.lookup(@resource_name)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
@
|
35
|
+
def set_popover_params
|
36
|
+
@popover_params =
|
37
37
|
if params[:params].blank?
|
38
|
-
@
|
38
|
+
@popover_params = {}.freeze
|
39
39
|
else
|
40
40
|
raw_params = JSON.parse(params[:params])
|
41
41
|
card_params = Coupdoeil::Params.deserialize(raw_params).sole
|
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
module Coupdoeil
|
4
4
|
module ApplicationHelper
|
5
|
-
def
|
5
|
+
def coupdoeil_popover_tag(popover, options = nil, **attributes_or_options, &)
|
6
6
|
if options.present?
|
7
7
|
attributes = attributes_or_options
|
8
8
|
else
|
9
|
-
options = attributes_or_options.extract!(*
|
9
|
+
options = attributes_or_options.extract!(*Popover::OptionsSet::OPTION_NAMES)
|
10
10
|
attributes = attributes_or_options
|
11
11
|
end
|
12
|
-
|
13
|
-
render(Coupdoeil::Tag.new(
|
12
|
+
popover_options = options
|
13
|
+
render(Coupdoeil::Tag.new(popover:, popover_options:, attributes:), &)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {closeNow} from "../
|
5
|
-
import {addToCurrents} from "../
|
1
|
+
import {PopoverController} from '../popover/controller'
|
2
|
+
import {openPopover} from '../popover/opening'
|
3
|
+
import {POPOVER_SELECTOR} from "../popover/config";
|
4
|
+
import {closeNow} from "../popover/closing";
|
5
|
+
import {addToCurrents} from "../popover/current";
|
6
6
|
|
7
7
|
function generateUniqueId() {
|
8
8
|
const array = new Uint32Array(1)
|
@@ -14,21 +14,21 @@ export default class extends HTMLElement {
|
|
14
14
|
constructor() {
|
15
15
|
super()
|
16
16
|
this.uniqueId = generateUniqueId()
|
17
|
-
this.
|
17
|
+
this.popoverController = new PopoverController(this)
|
18
18
|
}
|
19
19
|
|
20
|
-
|
21
|
-
if (this.
|
20
|
+
openPopover(triggerElement = null, callbacks) {
|
21
|
+
if (this.openingPopover || this.popoverController.isOpen || this.disabled || triggerElement === this) return;
|
22
22
|
|
23
|
-
this.
|
23
|
+
this.openingPopover = true
|
24
24
|
|
25
|
-
const parent = this.closest(
|
25
|
+
const parent = this.closest(POPOVER_SELECTOR)?.controller
|
26
26
|
addToCurrents(this)
|
27
|
-
return
|
27
|
+
return openPopover(this.popoverController, { parent, ...callbacks })
|
28
28
|
}
|
29
29
|
|
30
|
-
|
31
|
-
closeNow(this.
|
30
|
+
closePopover() {
|
31
|
+
closeNow(this.popoverController)
|
32
32
|
}
|
33
33
|
|
34
34
|
get disabled() {
|
@@ -1,67 +1,67 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {noTriggeredOnClick} from "../
|
4
|
-
import {closeAllNow, closeChildrenNow, closeNow} from "../
|
1
|
+
import {POPOVER_SELECTOR} from "../popover/config";
|
2
|
+
import {isElementClosePopoverButton} from "../popover/state_check";
|
3
|
+
import {noTriggeredOnClick} from "../popover/attributes";
|
4
|
+
import {closeAllNow, closeChildrenNow, closeNow} from "../popover/closing";
|
5
5
|
|
6
6
|
export const coupdoeilOnClickEvent = ({ target: clickedElement }) => {
|
7
7
|
const coupdoeilElement = clickedElement.closest('coup-doeil')
|
8
|
-
const
|
8
|
+
const popoverElement = clickedElement.closest(POPOVER_SELECTOR)
|
9
9
|
|
10
|
-
if (coupdoeilElement &&
|
11
|
-
|
10
|
+
if (coupdoeilElement && popoverElement) {
|
11
|
+
handleClickedCoupdoeilWithinPopover(coupdoeilElement, popoverElement, clickedElement)
|
12
12
|
}
|
13
13
|
else if (coupdoeilElement) {
|
14
|
-
|
14
|
+
handleClickedCoupdoeilOutsidePopover(coupdoeilElement, clickedElement)
|
15
15
|
}
|
16
|
-
else if (
|
17
|
-
|
16
|
+
else if (popoverElement) {
|
17
|
+
handleClickOutsideCoupdoeilButWithinPopover(popoverElement, clickedElement)
|
18
18
|
}
|
19
19
|
else {
|
20
|
-
|
20
|
+
handleClickOutsideCoupdoeilAndPopover()
|
21
21
|
}
|
22
22
|
}
|
23
23
|
|
24
|
-
function
|
25
|
-
const
|
26
|
-
if(noTriggeredOnClick(
|
24
|
+
function handleClickedCoupdoeilWithinPopover(coupdoeilElement, _popoverElement, clickedElement) {
|
25
|
+
const popover = coupdoeilElement.popoverController
|
26
|
+
if(noTriggeredOnClick(popover))
|
27
27
|
return;
|
28
28
|
|
29
|
-
if (
|
30
|
-
// second click on an open
|
31
|
-
closeNow(
|
29
|
+
if (popover.isOpen) {
|
30
|
+
// second click on an open popover trigger closes it
|
31
|
+
closeNow(popover)
|
32
32
|
} else {
|
33
|
-
// first click on a closed
|
34
|
-
// If any other
|
35
|
-
coupdoeilElement.
|
33
|
+
// first click on a closed popover trigger opens it
|
34
|
+
// If any other popover is open, it is the parent popover, hence it should not be closed.
|
35
|
+
coupdoeilElement.openPopover(clickedElement)
|
36
36
|
}
|
37
37
|
}
|
38
38
|
|
39
|
-
function
|
40
|
-
const
|
41
|
-
if(noTriggeredOnClick(
|
39
|
+
function handleClickedCoupdoeilOutsidePopover(coupdoeilElement, clickedElement) {
|
40
|
+
const popover = coupdoeilElement.popoverController
|
41
|
+
if(noTriggeredOnClick(popover))
|
42
42
|
return;
|
43
43
|
|
44
|
-
if (
|
45
|
-
// second click on an open
|
46
|
-
closeNow(
|
44
|
+
if (popover.isOpen) {
|
45
|
+
// second click on an open popover trigger closes it
|
46
|
+
closeNow(popover)
|
47
47
|
} else {
|
48
|
-
// close any other open
|
48
|
+
// close any other open popover
|
49
49
|
closeAllNow()
|
50
|
-
// first click on a closed
|
51
|
-
coupdoeilElement.
|
50
|
+
// first click on a closed popover trigger opens it
|
51
|
+
coupdoeilElement.openPopover(clickedElement)
|
52
52
|
}
|
53
53
|
}
|
54
54
|
|
55
|
-
function
|
56
|
-
const
|
55
|
+
function handleClickOutsideCoupdoeilButWithinPopover(popoverElement, clickedElement) {
|
56
|
+
const popover = popoverElement.controller;
|
57
57
|
|
58
|
-
if (
|
59
|
-
closeNow(
|
60
|
-
} else if (
|
61
|
-
closeChildrenNow(
|
58
|
+
if (isElementClosePopoverButton(clickedElement)) {
|
59
|
+
closeNow(popover)
|
60
|
+
} else if (popover.children.size > 0) {
|
61
|
+
closeChildrenNow(popover)
|
62
62
|
}
|
63
63
|
}
|
64
64
|
|
65
|
-
function
|
65
|
+
function handleClickOutsideCoupdoeilAndPopover() {
|
66
66
|
closeAllNow()
|
67
67
|
}
|
@@ -1,89 +1,89 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {notTriggeredOnHover} from "../
|
1
|
+
import {POPOVER_SELECTOR} from "../popover/config";
|
2
|
+
import {isAnyPopoverOpened} from "../popover/state_check";
|
3
|
+
import {notTriggeredOnHover} from "../popover/attributes";
|
4
4
|
import {
|
5
5
|
cancelCloseRequest,
|
6
6
|
closeChildrenNow,
|
7
7
|
closeOnHoverChildrenLater,
|
8
8
|
closeTriggeredOnHoverLater,
|
9
9
|
closeTriggeredOnHoverNowUnlessAncestor
|
10
|
-
} from "../
|
11
|
-
import {addToCurrents as
|
10
|
+
} from "../popover/closing";
|
11
|
+
import {addToCurrents as addToCurrentPopovers} from "../popover/current";
|
12
12
|
|
13
13
|
export const onMouseOver = ({ target: hoveredElement }) => {
|
14
14
|
const coupdoeilElement = hoveredElement.closest('coup-doeil')
|
15
|
-
const
|
15
|
+
const popoverElement = hoveredElement.closest(POPOVER_SELECTOR)
|
16
16
|
|
17
|
-
if (coupdoeilElement &&
|
18
|
-
|
17
|
+
if (coupdoeilElement && popoverElement) {
|
18
|
+
handleMouseOverCoupdoeilWithinPopover(coupdoeilElement, popoverElement, hoveredElement)
|
19
19
|
}
|
20
20
|
else if (coupdoeilElement) {
|
21
|
-
|
21
|
+
handleMouseOverCoupdoeilOutsidePopover(coupdoeilElement, hoveredElement)
|
22
22
|
}
|
23
|
-
else if (
|
24
|
-
|
23
|
+
else if (popoverElement) {
|
24
|
+
handleOverOutsideCoupdoeilButWithinPopover(popoverElement)
|
25
25
|
}
|
26
26
|
else {
|
27
|
-
|
27
|
+
handleOverOutsideCoupdoeilAndPopover()
|
28
28
|
}
|
29
29
|
}
|
30
30
|
|
31
|
-
function
|
32
|
-
const
|
33
|
-
const
|
34
|
-
if(notTriggeredOnHover(
|
31
|
+
function handleMouseOverCoupdoeilWithinPopover(coupdoeilElement, popoverElement, hoveredElement) {
|
32
|
+
const childPopover = coupdoeilElement.popoverController
|
33
|
+
const parentPopover = popoverElement.controller
|
34
|
+
if(notTriggeredOnHover(childPopover))
|
35
35
|
return;
|
36
36
|
|
37
|
-
if (
|
38
|
-
// when the mouse goes back from child
|
39
|
-
// it means that this child
|
40
|
-
closeChildrenNow(
|
37
|
+
if (childPopover.isOpen) {
|
38
|
+
// when the mouse goes back from child popover to its coupdoeil element within parent popover
|
39
|
+
// it means that this child popover was already open
|
40
|
+
closeChildrenNow(childPopover)
|
41
41
|
} else {
|
42
|
-
// ensures to close other children
|
43
|
-
closeChildrenNow(
|
44
|
-
// should also close any open
|
45
|
-
coupdoeilElement.
|
42
|
+
// ensures to close other children popovers before opening the one that current one
|
43
|
+
closeChildrenNow(parentPopover)
|
44
|
+
// should also close any open popover outside of parent
|
45
|
+
coupdoeilElement.openPopover(hoveredElement)
|
46
46
|
}
|
47
47
|
}
|
48
48
|
|
49
|
-
function
|
50
|
-
const
|
51
|
-
if(notTriggeredOnHover(
|
49
|
+
function handleMouseOverCoupdoeilOutsidePopover(coupdoeilElement, hoveredElement) {
|
50
|
+
const popover = coupdoeilElement.popoverController
|
51
|
+
if(notTriggeredOnHover(popover))
|
52
52
|
return;
|
53
53
|
|
54
|
-
if (
|
55
|
-
// Close any other open
|
56
|
-
coupdoeilElement.
|
57
|
-
} else if (
|
58
|
-
//
|
59
|
-
// and ensures the
|
60
|
-
cancelCloseRequest(
|
61
|
-
|
54
|
+
if (popover.isClosed) {
|
55
|
+
// Close any other open popover before opening this one
|
56
|
+
coupdoeilElement.openPopover(hoveredElement, { beforeDisplay: closeTriggeredOnHoverNowUnlessAncestor })
|
57
|
+
} else if (popover.closingRequest) {
|
58
|
+
// popover is still open but was requested to close, then it clear this closing request
|
59
|
+
// and ensures the popovers stays in current popovers register
|
60
|
+
cancelCloseRequest(popover)
|
61
|
+
addToCurrentPopovers(coupdoeilElement)
|
62
62
|
}
|
63
63
|
}
|
64
64
|
|
65
|
-
function
|
66
|
-
// mouse is not within any
|
67
|
-
// Therefore all
|
68
|
-
if (
|
65
|
+
function handleOverOutsideCoupdoeilAndPopover() {
|
66
|
+
// mouse is not within any popover and not over any coupdoeil element
|
67
|
+
// Therefore all popovers that trigger on hover should be closed if any is open.
|
68
|
+
if (isAnyPopoverOpened()) {
|
69
69
|
closeTriggeredOnHoverLater()
|
70
70
|
}
|
71
71
|
}
|
72
72
|
|
73
|
-
function
|
74
|
-
const
|
73
|
+
function handleOverOutsideCoupdoeilButWithinPopover(popoverElement) {
|
74
|
+
const popover = popoverElement.controller
|
75
75
|
|
76
|
-
if (
|
77
|
-
//
|
78
|
-
// and ensures the
|
79
|
-
// This typically happens when mouse was on coupdoeil element, then it moves toward the
|
80
|
-
// but because of a small gap, it triggers the closing request, but when the mouse finally enters the
|
76
|
+
if (popover.closingRequest) {
|
77
|
+
// popover is still open but was requested to close, then it clears this closing request
|
78
|
+
// and ensures the popovers stays in current popovers register
|
79
|
+
// This typically happens when mouse was on coupdoeil element, then it moves toward the popover
|
80
|
+
// but because of a small gap, it triggers the closing request, but when the mouse finally enters the popover
|
81
81
|
// this closing request must be aborted.
|
82
|
-
cancelCloseRequest(
|
83
|
-
|
84
|
-
} else if (
|
85
|
-
// Happens when a child
|
86
|
-
// but stays within the parent
|
87
|
-
closeOnHoverChildrenLater(
|
82
|
+
cancelCloseRequest(popover)
|
83
|
+
addToCurrentPopovers(popover.coupdoeilElement)
|
84
|
+
} else if (popover.children.size > 0) {
|
85
|
+
// Happens when a child popover was open but mouse moved outside of it or its coupdoeil element,
|
86
|
+
// but stays within the parent popover
|
87
|
+
closeOnHoverChildrenLater(popover)
|
88
88
|
}
|
89
89
|
}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import {coupdoeilOnClickEvent} from "./events/onclick";
|
2
2
|
import {onMouseOver} from "./events/onmouseover";
|
3
3
|
|
4
|
-
import {
|
5
|
-
import {clearAll} from "./
|
4
|
+
import {clearPopoverContentCache} from "./popover/cache";
|
5
|
+
import {clearAll} from "./popover/closing";
|
6
6
|
|
7
7
|
document.addEventListener("DOMContentLoaded", () => {
|
8
|
-
|
8
|
+
clearPopoverContentCache()
|
9
9
|
document.addEventListener("click", coupdoeilOnClickEvent)
|
10
10
|
document.documentElement.addEventListener("mouseover", onMouseOver, { passive: true })
|
11
11
|
|
@@ -15,7 +15,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
15
15
|
})
|
16
16
|
document.addEventListener('turbo:load', (_event) => {
|
17
17
|
clearAll()
|
18
|
-
|
18
|
+
clearPopoverContentCache()
|
19
19
|
})
|
20
20
|
}
|
21
21
|
})
|
@@ -1 +1 @@
|
|
1
|
-
import './
|
1
|
+
import './popover'
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import {extractOptionFromElement} from "./optionsParser";
|
2
2
|
|
3
3
|
export function getType(controller) {
|
4
|
-
return controller.coupdoeilElement.getAttribute('
|
4
|
+
return controller.coupdoeilElement.getAttribute('popover-type')
|
5
5
|
}
|
6
6
|
|
7
7
|
export function getParams(controller) {
|
8
|
-
return controller.coupdoeilElement.getAttribute('
|
8
|
+
return controller.coupdoeilElement.getAttribute('popover-params')
|
9
9
|
}
|
10
10
|
|
11
11
|
export function getTrigger(controller) {
|
@@ -29,5 +29,5 @@ export function notTriggeredOnHover(controller) {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
export function preloadedContentElement(controller) {
|
32
|
-
return controller.coupdoeilElement.querySelector('.
|
32
|
+
return controller.coupdoeilElement.querySelector('.popover-content')
|
33
33
|
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import {getParams, getType, preloadedContentElement} from './attributes'
|
2
|
+
|
3
|
+
export const popoverContentHTMLMap = new Map()
|
4
|
+
|
5
|
+
function cacheMapKey(controller) {
|
6
|
+
if (preloadedContentElement(controller)) {
|
7
|
+
return controller.coupdoeilElement.uniqueId
|
8
|
+
}
|
9
|
+
return getType(controller) + getParams(controller)
|
10
|
+
}
|
11
|
+
|
12
|
+
export function getPopoverContentHTML(controller) {
|
13
|
+
return popoverContentHTMLMap.get(cacheMapKey(controller))
|
14
|
+
}
|
15
|
+
|
16
|
+
export function setPopoverContentHTML(controller, value) {
|
17
|
+
popoverContentHTMLMap.set(cacheMapKey(controller), value)
|
18
|
+
}
|
19
|
+
|
20
|
+
export function clearPopoverContentCache() {
|
21
|
+
popoverContentHTMLMap.clear()
|
22
|
+
}
|