Core: Add support for Web Components (#2493)

Co-authored-by: Daniel Hobi <daniel.hobi@swisslearninghub.com>
This commit is contained in:
Daniel Hobi
2024-06-28 17:10:19 +02:00
committed by GitHub
parent 0f8400fc55
commit 75f51237e4
8 changed files with 70 additions and 12 deletions

View File

@@ -1,5 +1,8 @@
{
"preset": "jquery",
"maximumLineLength": null,
"requireCamelCaseOrUpperCaseIdentifiers": null
"requireCamelCaseOrUpperCaseIdentifiers": null,
"excludeFiles": [
"test/custom-elements.js"
]
}

View File

@@ -4,3 +4,4 @@ test/qunit/
dist/
demo/
*.min.js
test/custom-elements.js

View File

@@ -115,7 +115,17 @@ grunt.initConfig( {
}
},
qunit: {
files: "test/index.html"
files: "test/index.html",
options: {
puppeteer: {
args: [
"--headless",
"--disable-web-security",
"--allow-file-access-from-files"
]
},
timeout: 10000
}
},
jshint: {
options: {

View File

@@ -45,7 +45,7 @@
"grunt-contrib-concat": "1.0.1",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-jshint": "1.0.0",
"grunt-contrib-qunit": "1.2.0",
"grunt-contrib-qunit": "10.0.0",
"grunt-contrib-uglify": "1.0.1",
"grunt-contrib-watch": "1.0.0",
"grunt-jscs": "2.8.0",

View File

@@ -275,6 +275,7 @@ $.extend( $.validator, {
onsubmit: true,
ignore: ":hidden",
ignoreTitle: false,
customElements: [],
onfocusin: function( element ) {
this.lastActive = element;
@@ -422,17 +423,17 @@ $.extend( $.validator, {
settings[ eventType ].call( validator, this, event );
}
}
var focusListeners = [ ":text", "[type='password']", "[type='file']", "select", "textarea", "[type='number']", "[type='search']",
"[type='tel']", "[type='url']", "[type='email']", "[type='datetime']", "[type='date']", "[type='month']",
"[type='week']", "[type='time']", "[type='datetime-local']", "[type='range']", "[type='color']",
"[type='radio']", "[type='checkbox']", "[contenteditable]", "[type='button']" ];
var clickListeners = [ "select", "option", "[type='radio']", "[type='checkbox']" ];
$( this.currentForm )
.on( "focusin.validate focusout.validate keyup.validate",
":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
.on( "focusin.validate focusout.validate keyup.validate", focusListeners.concat( this.settings.customElements ).join( ", " ), delegate )
// Support: Chrome, oldIE
// "select" is provided as event.target when clicking a option
.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
.on( "click.validate", clickListeners.concat( this.settings.customElements ).join( ", " ), delegate );
if ( this.settings.invalidHandler ) {
$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
@@ -629,11 +630,12 @@ $.extend( $.validator, {
elements: function() {
var validator = this,
rulesCache = {};
rulesCache = {},
selectors = [ "input", "select", "textarea", "[contenteditable]" ];
// Select all valid inputs inside the form (no submit or reset buttons)
return $( this.currentForm )
.find( "input, select, textarea, [contenteditable]" )
.find( selectors.concat( this.settings.customElements ).join( ", " ) )
.not( ":submit, :reset, :image, :disabled" )
.not( this.settings.ignore )
.filter( function() {

17
test/custom-elements.js Normal file
View File

@@ -0,0 +1,17 @@
class CustomTextElement extends HTMLElement {
static formAssociated = true;
static observedAttributes = ["name", "id"];
constructor() {
super();
this.internals_ = this.attachInternals();
}
get form() {
return this.internals_ != null ? this.internals_.form : null;
}
get name() {
return this.getAttribute("name");
}
}
window.customElements.define("custom-text", CustomTextElement);

View File

@@ -11,6 +11,7 @@
<script src="../lib/jquery.mockjax.js"></script>
<script src="../dist/jquery.validate.js"></script>
<script src="../dist/additional-methods.js"></script>
<script src="custom-elements.js"></script>
<script src="test.js"></script>
<script src="rules.js"></script>
<script src="messages.js"></script>
@@ -472,6 +473,9 @@
</form>
<form id="escapeHtmlForm2">
<input name="escapeHtmlForm2text" id="escapeHtmlForm2text" data-rule-required="true" />
</form>
<form id="customElementsForm">
<custom-text name="customTextElement" id="customTextElement" />
</form>
</div>
</body>

View File

@@ -2786,3 +2786,24 @@ QUnit.test( "stopRequest() should submit the form once pendingRequests === 0", f
// Submit the form
$( button ).click();
} );
QUnit.test( "Assign rules to customElement via .validate() method", function( assert ) {
var form = $( "#customElementsForm" );
var v = form.validate( {
customElements: [ "custom-text" ],
rules: {
customTextElement: {
required: true
}
}
} );
var customTextElementRules = $( "#customTextElement", form ).rules();
var expectedRules = { required: true };
assert.deepEqual(
customTextElementRules, expectedRules, "The rules should be the same"
);
v.form();
assert.equal( v.numberOfInvalids(), 1, "The form has one error" );
} );