Mercurial > hg > isophonics-drupal-site
comparison core/misc/dialog/off-canvas.es6.js @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
13:5fb285c0d0e3 | 14:1fec387a4317 |
---|---|
1 /** | |
2 * @file | |
3 * Drupal's off-canvas library. | |
4 */ | |
5 | |
6 (($, Drupal, debounce, displace) => { | |
7 /** | |
8 * Off-canvas dialog implementation using jQuery Dialog. | |
9 * | |
10 * Transforms the regular dialogs created using Drupal.dialog when the dialog | |
11 * element equals '#drupal-off-canvas' into an side-loading dialog. | |
12 * | |
13 * @namespace | |
14 */ | |
15 Drupal.offCanvas = { | |
16 | |
17 /** | |
18 * The minimum width to use body displace needs to match the width at which | |
19 * the tray will be 100% width. @see core/misc/dialog/off-canvas.css | |
20 * | |
21 * @type {Number} | |
22 */ | |
23 minDisplaceWidth: 768, | |
24 | |
25 /** | |
26 * Wrapper used to position off-canvas dialog. | |
27 * | |
28 * @type {jQuery} | |
29 */ | |
30 $mainCanvasWrapper: $('[data-off-canvas-main-canvas]'), | |
31 | |
32 /** | |
33 * Determines if an element is an off-canvas dialog. | |
34 * | |
35 * @param {jQuery} $element | |
36 * The dialog element. | |
37 * | |
38 * @return {bool} | |
39 * True this is currently an off-canvas dialog. | |
40 */ | |
41 isOffCanvas($element) { | |
42 return $element.is('#drupal-off-canvas'); | |
43 }, | |
44 | |
45 /** | |
46 * Remove off-canvas dialog events. | |
47 * | |
48 * @param {jQuery} $element | |
49 * The target element. | |
50 */ | |
51 removeOffCanvasEvents($element) { | |
52 $element.off('.off-canvas'); | |
53 $(document).off('.off-canvas'); | |
54 $(window).off('.off-canvas'); | |
55 }, | |
56 | |
57 /** | |
58 * Handler fired before an off-canvas dialog has been opened. | |
59 * | |
60 * @param {Object} settings | |
61 * Settings related to the composition of the dialog. | |
62 * | |
63 * @return {undefined} | |
64 */ | |
65 beforeCreate({ settings, $element }) { | |
66 // Clean up previous dialog event handlers. | |
67 Drupal.offCanvas.removeOffCanvasEvents($element); | |
68 | |
69 $('body').addClass('js-off-canvas-dialog-open'); | |
70 // @see http://api.jqueryui.com/position/ | |
71 settings.position = { | |
72 my: 'left top', | |
73 at: `${Drupal.offCanvas.getEdge()} top`, | |
74 of: window, | |
75 }; | |
76 | |
77 /** | |
78 * Applies initial height to dialog based on window height. | |
79 * @see http://api.jqueryui.com/dialog for all dialog options. | |
80 */ | |
81 settings.height = $(window).height(); | |
82 }, | |
83 | |
84 /** | |
85 * Handler fired after an off-canvas dialog has been closed. | |
86 * | |
87 * @return {undefined} | |
88 */ | |
89 beforeClose({ $element }) { | |
90 $('body').removeClass('js-off-canvas-dialog-open'); | |
91 // Remove all *.off-canvas events | |
92 Drupal.offCanvas.removeOffCanvasEvents($element); | |
93 | |
94 Drupal.offCanvas.$mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`, 0); | |
95 }, | |
96 | |
97 /** | |
98 * Handler fired when an off-canvas dialog has been opened. | |
99 * | |
100 * @param {jQuery} $element | |
101 * The off-canvas dialog element. | |
102 * @param {Object} settings | |
103 * Settings related to the composition of the dialog. | |
104 * | |
105 * @return {undefined} | |
106 */ | |
107 afterCreate({ $element, settings }) { | |
108 const eventData = { settings, $element, offCanvasDialog: this }; | |
109 | |
110 $element | |
111 .on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.handleDialogResize) | |
112 .on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.bodyPadding); | |
113 | |
114 Drupal.offCanvas.getContainer($element).attr(`data-offset-${Drupal.offCanvas.getEdge()}`, ''); | |
115 | |
116 $(window) | |
117 .on('resize.off-canvas', eventData, debounce(Drupal.offCanvas.resetSize, 100)) | |
118 .trigger('resize.off-canvas'); | |
119 }, | |
120 | |
121 /** | |
122 * Toggle classes based on title existence. | |
123 * Called with Drupal.offCanvas.afterCreate. | |
124 * | |
125 * @param {Object} settings | |
126 * Settings related to the composition of the dialog. | |
127 * | |
128 * @return {undefined} | |
129 */ | |
130 render({ settings }) { | |
131 $('.ui-dialog-off-canvas, .ui-dialog-off-canvas .ui-dialog-titlebar').toggleClass('ui-dialog-empty-title', !settings.title); | |
132 }, | |
133 | |
134 /** | |
135 * Adjusts the dialog on resize. | |
136 * | |
137 * @param {jQuery.Event} event | |
138 * The event triggered. | |
139 * @param {object} event.data | |
140 * Data attached to the event. | |
141 */ | |
142 handleDialogResize(event) { | |
143 const $element = event.data.$element; | |
144 const $container = Drupal.offCanvas.getContainer($element); | |
145 | |
146 const $offsets = $container.find('> :not(#drupal-off-canvas, .ui-resizable-handle)'); | |
147 let offset = 0; | |
148 | |
149 // Let scroll element take all the height available. | |
150 $element.css({ height: 'auto' }); | |
151 const modalHeight = $container.height(); | |
152 | |
153 $offsets.each((i, e) => { | |
154 offset += $(e).outerHeight(); | |
155 }); | |
156 | |
157 // Take internal padding into account. | |
158 const scrollOffset = $element.outerHeight() - $element.height(); | |
159 $element.height(modalHeight - offset - scrollOffset); | |
160 }, | |
161 | |
162 /** | |
163 * Resets the size of the dialog. | |
164 * | |
165 * @param {jQuery.Event} event | |
166 * The event triggered. | |
167 * @param {object} event.data | |
168 * Data attached to the event. | |
169 */ | |
170 resetSize(event) { | |
171 const offsets = displace.offsets; | |
172 const $element = event.data.$element; | |
173 const container = Drupal.offCanvas.getContainer($element); | |
174 | |
175 const topPosition = (offsets.top !== 0 ? `+${offsets.top}` : ''); | |
176 const adjustedOptions = { | |
177 // @see http://api.jqueryui.com/position/ | |
178 position: { | |
179 my: `${Drupal.offCanvas.getEdge()} top`, | |
180 at: `${Drupal.offCanvas.getEdge()} top${topPosition}`, | |
181 of: window, | |
182 }, | |
183 }; | |
184 | |
185 container.css({ | |
186 position: 'fixed', | |
187 height: `${$(window).height() - (offsets.top + offsets.bottom)}px`, | |
188 }); | |
189 | |
190 $element | |
191 .dialog('option', adjustedOptions) | |
192 .trigger('dialogContentResize.off-canvas'); | |
193 }, | |
194 | |
195 /** | |
196 * Adjusts the body padding when the dialog is resized. | |
197 * | |
198 * @param {jQuery.Event} event | |
199 * The event triggered. | |
200 * @param {object} event.data | |
201 * Data attached to the event. | |
202 */ | |
203 bodyPadding(event) { | |
204 if ($('body').outerWidth() < Drupal.offCanvas.minDisplaceWidth) { | |
205 return; | |
206 } | |
207 const $element = event.data.$element; | |
208 const $container = Drupal.offCanvas.getContainer($element); | |
209 const $mainCanvasWrapper = Drupal.offCanvas.$mainCanvasWrapper; | |
210 | |
211 const width = $container.outerWidth(); | |
212 const mainCanvasPadding = $mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`); | |
213 if (width !== mainCanvasPadding) { | |
214 $mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`, `${width}px`); | |
215 $container.attr(`data-offset-${Drupal.offCanvas.getEdge()}`, width); | |
216 displace(); | |
217 } | |
218 }, | |
219 | |
220 /** | |
221 * The HTML element that surrounds the dialog. | |
222 * @param {HTMLElement} $element | |
223 * The dialog element. | |
224 * | |
225 * @return {HTMLElement} | |
226 * The containing element. | |
227 */ | |
228 getContainer($element) { | |
229 return $element.dialog('widget'); | |
230 }, | |
231 | |
232 /** | |
233 * The edge of the screen that the dialog should appear on. | |
234 * | |
235 * @return {string} | |
236 * The edge the tray will be shown on, left or right. | |
237 */ | |
238 getEdge() { | |
239 return document.documentElement.dir === 'rtl' ? 'left' : 'right'; | |
240 }, | |
241 }; | |
242 | |
243 /** | |
244 * Attaches off-canvas dialog behaviors. | |
245 * | |
246 * @type {Drupal~behavior} | |
247 * | |
248 * @prop {Drupal~behaviorAttach} attach | |
249 * Attaches event listeners for off-canvas dialogs. | |
250 */ | |
251 Drupal.behaviors.offCanvasEvents = { | |
252 attach: () => { | |
253 $(window).once('off-canvas').on({ | |
254 'dialog:beforecreate': (event, dialog, $element, settings) => { | |
255 if (Drupal.offCanvas.isOffCanvas($element)) { | |
256 Drupal.offCanvas.beforeCreate({ dialog, $element, settings }); | |
257 } | |
258 }, | |
259 'dialog:aftercreate': (event, dialog, $element, settings) => { | |
260 if (Drupal.offCanvas.isOffCanvas($element)) { | |
261 Drupal.offCanvas.render({ dialog, $element, settings }); | |
262 Drupal.offCanvas.afterCreate({ $element, settings }); | |
263 } | |
264 }, | |
265 'dialog:beforeclose': (event, dialog, $element) => { | |
266 if (Drupal.offCanvas.isOffCanvas($element)) { | |
267 Drupal.offCanvas.beforeClose({ dialog, $element }); | |
268 } | |
269 }, | |
270 }); | |
271 }, | |
272 }; | |
273 })(jQuery, Drupal, Drupal.debounce, Drupal.displace); |