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); + }); + }); + }); });