Skip to content

Commit 97aa749

Browse files
authored
Vendor jquery.are-you-sure with strict mode fixes (#26901)
Extract from #25940 and because #26743 does seem to need more work. This will be required if we are to run our JS in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). Previously, the two variables `$fields` and `$dirtyForms` polluted `window`: <img width="1145" alt="image" src="https://github.com/go-gitea/gitea/assets/115237/e0270a0e-b881-4ed7-9cc4-e9ab25c0a2bc">
1 parent 01e71e2 commit 97aa749

File tree

5 files changed

+196
-15
lines changed

5 files changed

+196
-15
lines changed

package-lock.json

Lines changed: 0 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
"escape-goat": "4.0.0",
2727
"fast-glob": "3.3.1",
2828
"jquery": "3.7.1",
29-
"jquery.are-you-sure": "1.9.0",
3029
"katex": "0.16.8",
3130
"license-checker-webpack-plugin": "0.2.1",
3231
"lightningcss-loader": "2.1.0",

web_src/js/features/common-global.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import $ from 'jquery';
2-
import 'jquery.are-you-sure';
2+
import '../vendor/jquery.are-you-sure.js';
33
import {clippie} from 'clippie';
44
import {createDropzone} from './dropzone.js';
55
import {initCompColorPicker} from './comp/ColorPicker.js';
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
// Fork of the upstream module. The only changes are the addition of `const` on
2+
// lines 93 and 161 to make it strict mode compatible.
3+
4+
/*!
5+
* jQuery Plugin: Are-You-Sure (Dirty Form Detection)
6+
* https://github.com/codedance/jquery.AreYouSure/
7+
*
8+
* Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/
9+
* Dual licensed under the MIT or GPL Version 2 licenses.
10+
* http://jquery.org/license
11+
*
12+
13+
* Version: 1.9.0
14+
* Date: 13th August 2014
15+
*/
16+
(function($) {
17+
18+
$.fn.areYouSure = function(options) {
19+
20+
var settings = $.extend(
21+
{
22+
'message' : 'You have unsaved changes!',
23+
'dirtyClass' : 'dirty',
24+
'change' : null,
25+
'silent' : false,
26+
'addRemoveFieldsMarksDirty' : false,
27+
'fieldEvents' : 'change keyup propertychange input',
28+
'fieldSelector': ":input:not(input[type=submit]):not(input[type=button])"
29+
}, options);
30+
31+
var getValue = function($field) {
32+
if ($field.hasClass('ays-ignore')
33+
|| $field.hasClass('aysIgnore')
34+
|| $field.attr('data-ays-ignore')
35+
|| $field.attr('name') === undefined) {
36+
return null;
37+
}
38+
39+
if ($field.is(':disabled')) {
40+
return 'ays-disabled';
41+
}
42+
43+
var val;
44+
var type = $field.attr('type');
45+
if ($field.is('select')) {
46+
type = 'select';
47+
}
48+
49+
switch (type) {
50+
case 'checkbox':
51+
case 'radio':
52+
val = $field.is(':checked');
53+
break;
54+
case 'select':
55+
val = '';
56+
$field.find('option').each(function(o) {
57+
var $option = $(this);
58+
if ($option.is(':selected')) {
59+
val += $option.val();
60+
}
61+
});
62+
break;
63+
default:
64+
val = $field.val();
65+
}
66+
67+
return val;
68+
};
69+
70+
var storeOrigValue = function($field) {
71+
$field.data('ays-orig', getValue($field));
72+
};
73+
74+
var checkForm = function(evt) {
75+
76+
var isFieldDirty = function($field) {
77+
var origValue = $field.data('ays-orig');
78+
if (undefined === origValue) {
79+
return false;
80+
}
81+
return (getValue($field) != origValue);
82+
};
83+
84+
var $form = ($(this).is('form'))
85+
? $(this)
86+
: $(this).parents('form');
87+
88+
// Test on the target first as it's the most likely to be dirty
89+
if (isFieldDirty($(evt.target))) {
90+
setDirtyStatus($form, true);
91+
return;
92+
}
93+
94+
const $fields = $form.find(settings.fieldSelector);
95+
96+
if (settings.addRemoveFieldsMarksDirty) {
97+
// Check if field count has changed
98+
var origCount = $form.data("ays-orig-field-count");
99+
if (origCount != $fields.length) {
100+
setDirtyStatus($form, true);
101+
return;
102+
}
103+
}
104+
105+
// Brute force - check each field
106+
var isDirty = false;
107+
$fields.each(function() {
108+
var $field = $(this);
109+
if (isFieldDirty($field)) {
110+
isDirty = true;
111+
return false; // break
112+
}
113+
});
114+
115+
setDirtyStatus($form, isDirty);
116+
};
117+
118+
var initForm = function($form) {
119+
var fields = $form.find(settings.fieldSelector);
120+
$(fields).each(function() { storeOrigValue($(this)); });
121+
$(fields).unbind(settings.fieldEvents, checkForm);
122+
$(fields).bind(settings.fieldEvents, checkForm);
123+
$form.data("ays-orig-field-count", $(fields).length);
124+
setDirtyStatus($form, false);
125+
};
126+
127+
var setDirtyStatus = function($form, isDirty) {
128+
var changed = isDirty != $form.hasClass(settings.dirtyClass);
129+
$form.toggleClass(settings.dirtyClass, isDirty);
130+
131+
// Fire change event if required
132+
if (changed) {
133+
if (settings.change) settings.change.call($form, $form);
134+
135+
if (isDirty) $form.trigger('dirty.areYouSure', [$form]);
136+
if (!isDirty) $form.trigger('clean.areYouSure', [$form]);
137+
$form.trigger('change.areYouSure', [$form]);
138+
}
139+
};
140+
141+
var rescan = function() {
142+
var $form = $(this);
143+
var fields = $form.find(settings.fieldSelector);
144+
$(fields).each(function() {
145+
var $field = $(this);
146+
if (!$field.data('ays-orig')) {
147+
storeOrigValue($field);
148+
$field.bind(settings.fieldEvents, checkForm);
149+
}
150+
});
151+
// Check for changes while we're here
152+
$form.trigger('checkform.areYouSure');
153+
};
154+
155+
var reinitialize = function() {
156+
initForm($(this));
157+
}
158+
159+
if (!settings.silent && !window.aysUnloadSet) {
160+
window.aysUnloadSet = true;
161+
$(window).bind('beforeunload', function() {
162+
const $dirtyForms = $("form").filter('.' + settings.dirtyClass);
163+
if ($dirtyForms.length == 0) {
164+
return;
165+
}
166+
// Prevent multiple prompts - seen on Chrome and IE
167+
if (navigator.userAgent.toLowerCase().match(/msie|chrome/)) {
168+
if (window.aysHasPrompted) {
169+
return;
170+
}
171+
window.aysHasPrompted = true;
172+
window.setTimeout(function() {window.aysHasPrompted = false;}, 900);
173+
}
174+
return settings.message;
175+
});
176+
}
177+
178+
return this.each(function(elem) {
179+
if (!$(this).is('form')) {
180+
return;
181+
}
182+
var $form = $(this);
183+
184+
$form.submit(function() {
185+
$form.removeClass(settings.dirtyClass);
186+
});
187+
$form.bind('reset', function() { setDirtyStatus($form, false); });
188+
// Add a custom events
189+
$form.bind('rescan.areYouSure', rescan);
190+
$form.bind('reinitialize.areYouSure', reinitialize);
191+
$form.bind('checkform.areYouSure', checkForm);
192+
initForm($form);
193+
});
194+
};
195+
})(jQuery);

webpack.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ export default {
206206
}).join('\n');
207207
},
208208
override: {
209-
'jquery.are-you-sure@*': {licenseName: 'MIT'}, // https://github.com/codedance/jquery.AreYouSure/pull/147
210209
'khroma@*': {licenseName: 'MIT'}, // https://github.com/fabiospampinato/khroma/pull/33
211210
},
212211
emitError: true,

0 commit comments

Comments
 (0)