diff --git a/addon/src/properties/property.js b/addon/src/properties/property.js
index b0ff179b..2dba07cf 100644
--- a/addon/src/properties/property.js
+++ b/addon/src/properties/property.js
@@ -1,4 +1,3 @@
-import { $ } from '../-private/jquery';
import { findOne } from '../-private/finders';
import { getter } from '../macros/index';
@@ -52,6 +51,20 @@ export function property(propertyName, selector, userOptions = {}) {
...userOptions,
};
- return $(findOne(this, selector, options)).prop(propertyName);
+ const element = findOne(this, selector, options);
+ const propName = normalizePropertyName(propertyName);
+
+ return element[propName];
});
}
+
+const camelCaseMap = {
+ tabindex: 'tabIndex',
+ readonly: 'readOnly',
+ maxlength: 'maxLength',
+ contenteditable: 'contentEditable',
+};
+
+function normalizePropertyName(propertyName) {
+ return camelCaseMap[propertyName] ?? propertyName;
+}
diff --git a/test-app/tests/unit/-private/properties/property-test.ts b/test-app/tests/unit/-private/properties/property-test.ts
index d23e454e..7a2baade 100644
--- a/test-app/tests/unit/-private/properties/property-test.ts
+++ b/test-app/tests/unit/-private/properties/property-test.ts
@@ -158,4 +158,166 @@ module('property', function (hooks) {
assert.ok(page.foo);
});
+
+ module('jquery compatibility', function () {
+ test('readonly', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'input',
+ lowercase: property('readonly'),
+ camelCase: property('readOnly'),
+ });
+
+ await this.createTemplate('');
+
+ assert.true(page.lowercase, 'lowercase');
+ assert.true(page.camelCase, 'camelCase');
+ });
+
+ test('not readonly', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'input',
+ lowecase: property('readonly'),
+ camelCase: property('readOnly'),
+ });
+
+ await this.createTemplate('');
+
+ assert.false(page.lowecase, 'lowercase');
+ assert.false(page.camelCase, 'camelCase');
+ });
+
+ test('maxlength', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'input',
+ lowercase: property('maxlength'),
+ camelCase: property('maxLength'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.lowercase, 1, 'lowercase');
+ assert.strictEqual(page.camelCase, 1, 'camelCase');
+ });
+
+ test('no maxlength', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'input',
+ lowercase: property('maxlength'),
+ camelCase: property('maxLength'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.lowercase, -1, 'lowercase');
+ assert.strictEqual(page.camelCase, -1, 'camelCase');
+ });
+
+ test('contenteditable', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'span',
+ lowercase: property('contenteditable'),
+ camelCase: property('contentEditable'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.lowercase, 'true', 'lowercase');
+ assert.strictEqual(page.camelCase, 'true', 'camelCase');
+ });
+
+ test('not contenteditable', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'span',
+ lowercase: property('contenteditable'),
+ camelCase: property('contentEditable'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.lowercase, 'inherit', 'lowercase');
+ assert.strictEqual(page.camelCase, 'inherit', 'camelCase');
+ });
+
+ test('non-standard', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'span',
+ lowercase: property('neverexisted'),
+ camelCase: property('neverExisted'),
+ dasherized: property('never-existed'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.lowercase, undefined, 'lowercase');
+ assert.strictEqual(page.camelCase, undefined, 'camelCase');
+ assert.strictEqual(page.dasherized, undefined, 'dash-erized');
+ });
+
+ test('[data-*]', async function (this: TestContext, assert) {
+ const page = create({
+ scope: 'span',
+ lowercase: property('data-test'),
+ camelCase: property('neverTest'),
+ dasherized: property('never-test'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.lowercase, undefined, 'lowercase');
+ assert.strictEqual(page.camelCase, undefined, 'camelCase');
+ assert.strictEqual(page.dasherized, undefined, 'dash-erized');
+ });
+
+ module('tabindex', function () {
+ test('camelCase', async function (this: TestContext, assert) {
+ const page = create({
+ foo: property('tabIndex', 'input'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.foo, 2);
+ });
+
+ test('explicitly specified', async function (this: TestContext, assert) {
+ const page = create({
+ foo: property('tabindex', 'input'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.foo, 2);
+ });
+
+ test('unspecified on interactive', async function (this: TestContext, assert) {
+ const page = create({
+ foo: property('tabindex', 'input'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.foo, 0);
+ });
+
+ test('unspecified on non-interactive', async function (this: TestContext, assert) {
+ const page = create({
+ foo: property('tabindex', 'span'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.foo, -1);
+ });
+
+ test('uspecified on an interactive link(with href)', async function (this: TestContext, assert) {
+ const page = create({
+ foo: property('tabindex', 'a'),
+ });
+
+ await this.createTemplate('');
+
+ assert.strictEqual(page.foo, 0);
+ });
+ });
+ });
});