PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / trunk
Secure Custom Fields vtrunk
6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / assets / src / js / _acf-tooltip.js
secure-custom-fields / assets / src / js Last commit date
bindings 6 months ago commands 1 week ago pro 1 week ago _acf-compatibility.js 1 year ago _acf-condition-types.js 7 months ago _acf-condition.js 1 year ago _acf-conditions.js 1 year ago _acf-field-accordion.js 6 months ago _acf-field-button-group.js 7 months ago _acf-field-checkbox.js 1 month ago _acf-field-color-picker.js 7 months ago _acf-field-date-picker.js 1 month ago _acf-field-date-time-picker.js 1 month ago _acf-field-file.js 1 month ago _acf-field-google-map.js 6 months ago _acf-field-icon-picker.js 1 month ago _acf-field-image.js 1 month ago _acf-field-link.js 1 year ago _acf-field-oembed.js 1 month ago _acf-field-page-link.js 1 year ago _acf-field-post-object.js 1 year ago _acf-field-radio.js 1 month ago _acf-field-range.js 1 year ago _acf-field-relationship.js 1 month ago _acf-field-select.js 1 month ago _acf-field-tab.js 3 weeks ago _acf-field-taxonomy.js 7 months ago _acf-field-time-picker.js 1 month ago _acf-field-true-false.js 1 month ago _acf-field-url.js 1 year ago _acf-field-user.js 1 year ago _acf-field-wysiwyg.js 1 month ago _acf-field.js 1 year ago _acf-fields.js 1 year ago _acf-helpers.js 1 year ago _acf-hooks.js 1 year ago _acf-internal-post-type.js 7 months ago _acf-media.js 1 week ago _acf-modal.js 1 year ago _acf-model.js 1 year ago _acf-notice.js 7 months ago _acf-panel.js 1 year ago _acf-popup.js 7 months ago _acf-postbox.js 1 year ago _acf-screen.js 10 months ago _acf-select2.js 1 year ago _acf-tinymce.js 6 months ago _acf-tooltip.js 10 months ago _acf-unload.js 1 year ago _acf-validation.js 1 month ago _acf.js 7 months ago _browse-fields-modal.js 7 months ago _field-group-compatibility.js 1 year ago _field-group-conditions.js 1 year ago _field-group-field.js 3 months ago _field-group-fields.js 10 months ago _field-group-locations.js 1 year ago _field-group-settings.js 1 year ago _field-group.js 10 months ago acf-escaped-html-notice.js 1 year ago acf-field-group.js 1 year ago acf-input.js 1 year ago acf-internal-post-type.js 1 year ago acf.js 1 year ago
_acf-tooltip.js
330 lines
1 ( function ( $, undefined ) {
2 acf.newTooltip = function ( props ) {
3 // ensure object
4 if ( typeof props !== 'object' ) {
5 props = { text: props };
6 }
7
8 // confirmRemove
9 if ( props.confirmRemove !== undefined ) {
10 props.textConfirm = acf.__( 'Remove' );
11 props.textCancel = acf.__( 'Cancel' );
12 return new TooltipConfirm( props );
13
14 // confirm
15 } else if ( props.confirm !== undefined ) {
16 return new TooltipConfirm( props );
17
18 // default
19 } else {
20 return new Tooltip( props );
21 }
22 };
23
24 var Tooltip = acf.Model.extend( {
25 data: {
26 text: '',
27 timeout: 0,
28 target: null,
29 },
30
31 tmpl: function () {
32 return '<div class="acf-tooltip"></div>';
33 },
34
35 setup: function ( props ) {
36 $.extend( this.data, props );
37 this.$el = $( this.tmpl() );
38 },
39
40 initialize: function () {
41 // render
42 this.render();
43
44 // append
45 this.show();
46
47 // position
48 this.position();
49
50 // timeout
51 var timeout = this.get( 'timeout' );
52 if ( timeout ) {
53 setTimeout( $.proxy( this.fade, this ), timeout );
54 }
55 },
56
57 update: function ( props ) {
58 $.extend( this.data, props );
59 this.initialize();
60 },
61
62 render: function () {
63 this.$el.text( this.get( 'text' ) );
64 },
65
66 show: function () {
67 $( 'body' ).append( this.$el );
68 },
69
70 hide: function () {
71 this.$el.remove();
72 },
73
74 fade: function () {
75 // add class
76 this.$el.addClass( 'acf-fade-up' );
77
78 // remove
79 this.setTimeout( function () {
80 this.remove();
81 }, 250 );
82 },
83
84 html: function ( html ) {
85 this.$el.html( html );
86 },
87
88 position: function () {
89 // vars
90 var $tooltip = this.$el;
91 var $target = this.get( 'target' );
92 if ( ! $target ) return;
93
94 // Reset position.
95 $tooltip
96 .removeClass( 'right left bottom top' )
97 .css( { top: 0, left: 0 } );
98
99 // Declare tolerance to edge of screen.
100 var tolerance = 10;
101
102 // Find target position.
103 var targetWidth = $target.outerWidth();
104 var targetHeight = $target.outerHeight();
105 var targetTop = $target.offset().top;
106 var targetLeft = $target.offset().left;
107
108 // Find tooltip position.
109 var tooltipWidth = $tooltip.outerWidth();
110 var tooltipHeight = $tooltip.outerHeight();
111 var tooltipTop = $tooltip.offset().top; // Should be 0, but WP media grid causes this to be 32 (toolbar padding).
112
113 // Assume default top alignment.
114 var top = targetTop - tooltipHeight - tooltipTop;
115 var left = targetLeft + targetWidth / 2 - tooltipWidth / 2;
116
117 // Check if too far left.
118 if ( left < tolerance ) {
119 $tooltip.addClass( 'right' );
120 left = targetLeft + targetWidth;
121 top =
122 targetTop +
123 targetHeight / 2 -
124 tooltipHeight / 2 -
125 tooltipTop;
126
127 // Check if too far right.
128 } else if (
129 left + tooltipWidth + tolerance >
130 $( window ).width()
131 ) {
132 $tooltip.addClass( 'left' );
133 left = targetLeft - tooltipWidth;
134 top =
135 targetTop +
136 targetHeight / 2 -
137 tooltipHeight / 2 -
138 tooltipTop;
139
140 // Check if too far up.
141 } else if ( top - $( window ).scrollTop() < tolerance ) {
142 $tooltip.addClass( 'bottom' );
143 top = targetTop + targetHeight - tooltipTop;
144
145 // No collision with edges.
146 } else {
147 $tooltip.addClass( 'top' );
148 }
149
150 // update css
151 $tooltip.css( { top: top, left: left } );
152 },
153 } );
154
155 var TooltipConfirm = Tooltip.extend( {
156 data: {
157 text: '',
158 textConfirm: '',
159 textCancel: '',
160 target: null,
161 targetConfirm: true,
162 confirm: function () {},
163 cancel: function () {},
164 context: false,
165 },
166
167 events: {
168 'click [data-event="cancel"]': 'onCancel',
169 'click [data-event="confirm"]': 'onConfirm',
170 },
171
172 addEvents: function () {
173 // add events
174 acf.Model.prototype.addEvents.apply( this );
175
176 // vars
177 var $document = $( document );
178 var $target = this.get( 'target' );
179
180 // add global 'cancel' click event
181 // - use timeout to avoid the current 'click' event triggering the onCancel function
182 this.setTimeout( function () {
183 this.on( $document, 'click', 'onCancel' );
184 } );
185
186 // add target 'confirm' click event
187 // - allow setting to control this feature
188 if ( this.get( 'targetConfirm' ) ) {
189 this.on( $target, 'click', 'onConfirm' );
190 }
191 },
192
193 removeEvents: function () {
194 // remove events
195 acf.Model.prototype.removeEvents.apply( this );
196
197 // vars
198 var $document = $( document );
199 var $target = this.get( 'target' );
200
201 // remove custom events
202 this.off( $document, 'click' );
203 this.off( $target, 'click' );
204 },
205
206 render: function () {
207 // defaults
208 var text = this.get( 'text' ) || acf.__( 'Are you sure?' );
209 var textConfirm = this.get( 'textConfirm' ) || acf.__( 'Yes' );
210 var textCancel = this.get( 'textCancel' ) || acf.__( 'No' );
211
212 // html
213 var html = [
214 text,
215 '<a href="#" data-event="confirm">' + textConfirm + '</a>',
216 '<a href="#" data-event="cancel">' + textCancel + '</a>',
217 ].join( ' ' );
218
219 // html
220 this.html( html );
221
222 // class
223 this.$el.addClass( '-confirm' );
224 },
225
226 onCancel: function ( e, $el ) {
227 // prevent default
228 e.preventDefault();
229 e.stopImmediatePropagation();
230
231 // callback
232 var callback = this.get( 'cancel' );
233 var context = this.get( 'context' ) || this;
234 callback.apply( context, arguments );
235
236 //remove
237 this.remove();
238 },
239
240 onConfirm: function ( e, $el ) {
241 // Prevent event from propagating completely to allow "targetConfirm" to be clicked.
242 e.preventDefault();
243 e.stopImmediatePropagation();
244
245 // callback
246 var callback = this.get( 'confirm' );
247 var context = this.get( 'context' ) || this;
248 callback.apply( context, arguments );
249
250 //remove
251 this.remove();
252 },
253 } );
254
255 // storage
256 acf.models.Tooltip = Tooltip;
257 acf.models.TooltipConfirm = TooltipConfirm;
258
259 /**
260 * tooltipManager
261 *
262 * description
263 *
264 * @date 17/4/18
265 * @since ACF 5.6.9
266 *
267 * @param type $var Description. Default.
268 * @return type Description.
269 */
270
271 var tooltipHoverHelper = new acf.Model( {
272 tooltip: false,
273
274 events: {
275 'mouseenter .acf-js-tooltip': 'showTitle',
276 'mouseup .acf-js-tooltip': 'hideTitle',
277 'mouseleave .acf-js-tooltip': 'hideTitle',
278 'focus .acf-js-tooltip': 'showTitle',
279 'blur .acf-js-tooltip': 'hideTitle',
280 'keyup .acf-js-tooltip': 'onKeyUp',
281 },
282
283 showTitle: function ( e, $el ) {
284 // vars
285 let title = $el.attr( 'title' );
286
287 // bail early if no title
288 if ( ! title ) {
289 return;
290 }
291
292 // clear title to avoid default browser tooltip
293 $el.attr( 'title', '' );
294
295 $el.data( 'acf-js-tooltip-title', title );
296 title = acf.strEscape( title );
297
298 // create
299 if ( ! this.tooltip ) {
300 this.tooltip = acf.newTooltip( {
301 text: title,
302 target: $el,
303 } );
304
305 // update
306 } else {
307 this.tooltip.update( {
308 text: title,
309 target: $el,
310 } );
311 }
312 },
313
314 hideTitle: function ( e, $el ) {
315 // hide tooltip
316 this.tooltip.hide();
317 $el.attr( 'title', $el.data( 'acf-js-tooltip-title' ) );
318
319 // restore title
320 $el.removeData( 'acf-js-tooltip-title' );
321 },
322
323 onKeyUp: function ( e, $el ) {
324 if ( 'Escape' === e.key ) {
325 this.hideTitle( e, $el );
326 }
327 },
328 } );
329 } )( jQuery );
330