From 7f38c88259d1bbf704dea488de9b4c7622df2a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl-Ian?= Date: Sun, 29 Jan 2023 15:50:56 -0500 Subject: [PATCH 1/2] Isolate jQuery integration code and tests --- npm/__tests__/features/cocooned.js | 4 +- npm/__tests__/features/plugins/limit.js | 2 +- npm/__tests__/features/plugins/reorderable.js | 2 +- npm/__tests__/integration/cocoon/classes.js | 2 +- npm/__tests__/integration/cocoon/events.js | 2 +- npm/__tests__/integration/cocoon/onLoad.js | 28 ------ npm/__tests__/integration/jquery.js | 47 +++++++++ npm/__tests__/integration/jquery/events.js | 96 ------------------- npm/__tests__/integration/jquery/onLoad.js | 25 ----- npm/__tests__/integration/jquery/plugin.js | 27 ------ npm/__tests__/integration/rails.js | 2 +- npm/__tests__/jest.config.js | 6 +- npm/__tests__/support/jquery.js | 15 --- npm/__tests__/support/matchers.js | 1 - npm/__tests__/unit/integrations/jquery.js | 44 +++++++++ npm/cocooned.js | 30 ++---- npm/index.js | 19 ++++ npm/jquery.js | 15 +++ npm/src/cocooned/base.js | 11 +++ package.json | 2 - yarn.lock | 91 +----------------- 21 files changed, 154 insertions(+), 317 deletions(-) delete mode 100644 npm/__tests__/integration/cocoon/onLoad.js create mode 100644 npm/__tests__/integration/jquery.js delete mode 100644 npm/__tests__/integration/jquery/events.js delete mode 100644 npm/__tests__/integration/jquery/onLoad.js delete mode 100644 npm/__tests__/integration/jquery/plugin.js delete mode 100644 npm/__tests__/support/jquery.js delete mode 100644 npm/__tests__/support/matchers.js create mode 100644 npm/__tests__/unit/integrations/jquery.js create mode 100644 npm/index.js create mode 100644 npm/jquery.js diff --git a/npm/__tests__/features/cocooned.js b/npm/__tests__/features/cocooned.js index ecf0888..c1f69fe 100644 --- a/npm/__tests__/features/cocooned.js +++ b/npm/__tests__/features/cocooned.js @@ -1,6 +1,6 @@ /* global given */ -import Cocooned from '@notus.sh/cocooned/cocooned' +import Cocooned from '@notus.sh/cocooned' import { jest } from '@jest/globals' import { clickEvent } from '@cocooned/tests/support/helpers' import { getItem, getItems, getAddLink, getRemoveLink } from '@cocooned/tests/support/selectors' @@ -34,7 +34,7 @@ describe('A basic Cocooned setup', () => { }) it('add a class to container', () => { - expect(given.container).toHaveClass('cocooned-container') + expect(given.container.classList).toContain('cocooned-container') }) describe('when add link is clicked', () => { diff --git a/npm/__tests__/features/plugins/limit.js b/npm/__tests__/features/plugins/limit.js index 865b079..7587641 100644 --- a/npm/__tests__/features/plugins/limit.js +++ b/npm/__tests__/features/plugins/limit.js @@ -1,6 +1,6 @@ /* global given */ -import Cocooned from '@notus.sh/cocooned/cocooned' +import Cocooned from '@notus.sh/cocooned' import { jest } from '@jest/globals' import { faker } from '@cocooned/tests/support/faker' import { clickEvent } from '@cocooned/tests/support/helpers' diff --git a/npm/__tests__/features/plugins/reorderable.js b/npm/__tests__/features/plugins/reorderable.js index 79f910f..3b57088 100644 --- a/npm/__tests__/features/plugins/reorderable.js +++ b/npm/__tests__/features/plugins/reorderable.js @@ -1,6 +1,6 @@ /* global given */ -import Cocooned from '@notus.sh/cocooned/cocooned' +import Cocooned from '@notus.sh/cocooned' import { jest } from '@jest/globals' import { faker } from '@cocooned/tests/support/faker' import { clickEvent } from '@cocooned/tests/support/helpers' diff --git a/npm/__tests__/integration/cocoon/classes.js b/npm/__tests__/integration/cocoon/classes.js index c405fd6..b98daf9 100644 --- a/npm/__tests__/integration/cocoon/classes.js +++ b/npm/__tests__/integration/cocoon/classes.js @@ -1,6 +1,6 @@ /* global given */ -import Cocooned from '@notus.sh/cocooned/cocooned' +import Cocooned from '@notus.sh/cocooned' import { jest } from '@jest/globals' import { setup, clickEvent } from '@cocooned/tests/support/helpers' diff --git a/npm/__tests__/integration/cocoon/events.js b/npm/__tests__/integration/cocoon/events.js index bdabf6f..7335d9d 100644 --- a/npm/__tests__/integration/cocoon/events.js +++ b/npm/__tests__/integration/cocoon/events.js @@ -1,6 +1,6 @@ /* global given */ -import Cocooned from '@notus.sh/cocooned/cocooned' +import Cocooned from '@notus.sh/cocooned' import { jest } from '@jest/globals' import { setup, clickEvent } from '@cocooned/tests/support/helpers' import { getAddLink, getRemoveLink } from '@cocooned/tests/support/selectors' diff --git a/npm/__tests__/integration/cocoon/onLoad.js b/npm/__tests__/integration/cocoon/onLoad.js deleted file mode 100644 index 7dc5ad0..0000000 --- a/npm/__tests__/integration/cocoon/onLoad.js +++ /dev/null @@ -1,28 +0,0 @@ -/* global given */ - -import Cocooned from '@notus.sh/cocooned/cocooned' - -describe('A Cocoon setup', () => { - given('template', () => ` -
-
- Add - -
-
- `) - given('insertionTemplate', () => '
') - given('container', () => document.querySelector('section')) - - beforeEach(async () => { - document.body.innerHTML = given.template - window.Cocooned = Cocooned - await import('../../../../app/assets/javascripts/cocoon') - }) - - it('is instanciated as a Cocooned instance', () => { - expect(given.container).toHaveClass('cocooned-container') - }) -}) diff --git a/npm/__tests__/integration/jquery.js b/npm/__tests__/integration/jquery.js new file mode 100644 index 0000000..e45e867 --- /dev/null +++ b/npm/__tests__/integration/jquery.js @@ -0,0 +1,47 @@ +/* global given */ + +import jQuery from 'jquery' +import { jest } from '@jest/globals' +import { clickEvent } from '@cocooned/tests/support/helpers' +import { getAddLink } from '@cocooned/tests/support/selectors' + +describe('A Cocooned setup with jQuery integration', () => { + given('html', () => ` +
+
+ Add + +
+
+ `) + given('template', () => '
') + given('container', () => document.querySelector('section')) + + beforeEach(async () => { + document.body.innerHTML = given.html + + // Expose jQuery globally and call auto-start as Jquery ready event does not fire in jest-dom + window.$ = window.jQuery = jQuery + await import('@notus.sh/cocooned/jquery').then(({ cocoonedAutoStart }) => cocoonedAutoStart()) + }) + + it('add a method to jQuery', () => { + expect(jQuery.fn).toEqual(expect.objectContaining({ cocooned: expect.any(Function) })) + }) + + it('instanciates Cocooned instances on startup', () => { + expect(given.container.classList).toContain('cocooned-container') + }) + + describe('when an event is fired', () => { + it('triggers jQuery event listeners', () => { + const listener = jest.fn() + $(given.container).on('cocoon:before-insert', listener) + getAddLink(given.container).dispatchEvent(clickEvent()) + + expect(listener).toHaveBeenCalled() + }) + }) +}) diff --git a/npm/__tests__/integration/jquery/events.js b/npm/__tests__/integration/jquery/events.js deleted file mode 100644 index 5c75060..0000000 --- a/npm/__tests__/integration/jquery/events.js +++ /dev/null @@ -1,96 +0,0 @@ -/* global given */ - -import Cocooned from '@notus.sh/cocooned/cocooned' -import { jest } from '@jest/globals' -import { faker } from '@cocooned/tests/support/faker' -import { setup, clickEvent } from '@cocooned/tests/support/helpers' -import { getAddLink, getMoveDownLink, getMoveUpLink, getRemoveLink } from '@cocooned/tests/support/selectors' - -describe('A Cocoon setup using jQuery events', () => { - given('template', () => ` -
-
- Add - -
-
- `) - given('insertionTemplate', () => ` -
- - Remove - Up - Down - - -
- `) - given('container', () => document.querySelector('section')) - given('cocooned', () => new Cocooned(given.container)) - given('addLink', () => getAddLink(given.container)) - - beforeEach(() => setup(document, given)) - - describe('when add link is clicked', () => { - it('fires a before-insert event', () => { - const listener = jest.fn() - $(given.container).on('cocoon:before-insert', listener) - given.addLink.dispatchEvent(clickEvent()) - - expect(listener).toHaveBeenCalled() - }) - }) - - describe('with an item', () => { - beforeEach(() => given.addLink.dispatchEvent(clickEvent())) - - describe('when remove link is clicked', () => { - given('removeLink', () => getRemoveLink(given.container)) - - it('fires a before-remove event', () => { - const listener = jest.fn() - $(given.container).on('cocoon:before-remove', listener) - given.removeLink.dispatchEvent(clickEvent()) - - expect(listener).toHaveBeenCalled() - }) - }) - }) - - describe('with more than one item', () => { - beforeEach(() => { - for (let i = 0; i < given.count; i++) { - given.addLink.dispatchEvent(clickEvent()) - } - }) - - given('count', () => faker.datatype.number({ min: 3, max: 5 })) - given('index', () => faker.datatype.number({ min: 1, max: given.count - 2 })) - - describe('when move up link is clicked', () => { - given('moveLink', () => getMoveUpLink(given.container, given.index)) - - it('fires a before-move event', () => { - const listener = jest.fn() - $(given.container).on('cocooned:before-move', listener) - given.moveLink.dispatchEvent(clickEvent()) - - expect(listener).toHaveBeenCalled() - }) - }) - - describe('when move down link is clicked', () => { - given('moveLink', () => getMoveDownLink(given.container, given.index)) - - it('fires a before-move event', () => { - const listener = jest.fn() - $(given.container).on('cocooned:before-move', listener) - given.moveLink.dispatchEvent(clickEvent()) - - expect(listener).toHaveBeenCalled() - }) - }) - }) -}) diff --git a/npm/__tests__/integration/jquery/onLoad.js b/npm/__tests__/integration/jquery/onLoad.js deleted file mode 100644 index e1268d1..0000000 --- a/npm/__tests__/integration/jquery/onLoad.js +++ /dev/null @@ -1,25 +0,0 @@ -/* global given */ - -describe('A Cocooned setup with cocooned-options', () => { - given('template', () => ` -
-
- Add - -
-
- `) - given('insertionTemplate', () => '
') - given('container', () => document.querySelector('section')) - - beforeEach(async () => { - document.body.innerHTML = given.template - await import('@notus.sh/cocooned/cocooned') - }) - - it('is instanciated as a Cocooned instance', () => { - expect(given.container).toHaveClass('cocooned-container') - }) -}) diff --git a/npm/__tests__/integration/jquery/plugin.js b/npm/__tests__/integration/jquery/plugin.js deleted file mode 100644 index 8e4c383..0000000 --- a/npm/__tests__/integration/jquery/plugin.js +++ /dev/null @@ -1,27 +0,0 @@ -/* global given */ - -import '@notus.sh/cocooned/cocooned' - -describe('A Cocooned setup', () => { - given('template', () => ` -
-
- Add - -
-
- `) - given('insertionTemplate', () => '
') - given('container', () => document.querySelector('section')) - - beforeEach(() => { - document.body.innerHTML = given.template - $(given.container).cocooned() - }) - - it('is instanciated as a Cocooned instance', () => { - expect(given.container).toHaveClass('cocooned-container') - }) -}) diff --git a/npm/__tests__/integration/rails.js b/npm/__tests__/integration/rails.js index 582da9c..db90880 100644 --- a/npm/__tests__/integration/rails.js +++ b/npm/__tests__/integration/rails.js @@ -1,6 +1,6 @@ /* global given */ -import Cocooned from '@notus.sh/cocooned/cocooned' +import Cocooned from '@notus.sh/cocooned' import { jest } from '@jest/globals' import { faker } from '@cocooned/tests/support/faker' import { setup, clickEvent } from '@cocooned/tests/support/helpers' diff --git a/npm/__tests__/jest.config.js b/npm/__tests__/jest.config.js index 1bef986..8abdb26 100644 --- a/npm/__tests__/jest.config.js +++ b/npm/__tests__/jest.config.js @@ -153,11 +153,7 @@ export default { // A list of paths to modules that run some code to configure or set up the // testing framework before each test - setupFilesAfterEnv: [ - 'givens/setup.js', - './support/jquery.js', - './support/matchers.js' - ], + setupFilesAfterEnv: ['givens/setup.js'], // The number of seconds after which a test is considered as slow and reported // as such in the results. diff --git a/npm/__tests__/support/jquery.js b/npm/__tests__/support/jquery.js deleted file mode 100644 index 706f397..0000000 --- a/npm/__tests__/support/jquery.js +++ /dev/null @@ -1,15 +0,0 @@ -import jQuery from 'jquery' - -// Change jQuery handler for the document ready event to immediately executed callbacks. -jQuery.fn.ready = function (fn) { - if (fn) fn() -} - -if (typeof global !== 'undefined') { - global.$ = global.jQuery = jQuery -} - -if (typeof window !== 'undefined') { - // jQuery needs to be available as window.$ for jquery-events-to-dom-events functions to work. - window.$ = jQuery -} diff --git a/npm/__tests__/support/matchers.js b/npm/__tests__/support/matchers.js deleted file mode 100644 index c44951a..0000000 --- a/npm/__tests__/support/matchers.js +++ /dev/null @@ -1 +0,0 @@ -import '@testing-library/jest-dom' diff --git a/npm/__tests__/unit/integrations/jquery.js b/npm/__tests__/unit/integrations/jquery.js new file mode 100644 index 0000000..3daedee --- /dev/null +++ b/npm/__tests__/unit/integrations/jquery.js @@ -0,0 +1,44 @@ +/* global given */ + +import { jQueryPluginMixin } from '@notus.sh/cocooned/src/integrations/jquery' +import { Base as Cocooned } from '@notus.sh/cocooned/src/cocooned/base' +import jQuery from 'jquery' +import { jest } from '@jest/globals' + +describe('jQueryPluginMixin', () => { + beforeEach(() => jQueryPluginMixin(jQuery, Cocooned)) + + it('add a method to jQuery', () => { + expect(jQuery.fn).toEqual(expect.objectContaining({ cocooned: expect.any(Function) })) + }) + + describe('jQuery.cocooned', () => { + beforeEach(() => { + document.body.innerHTML = given.html + Cocooned.create = given.mock + }) + afterEach(() => jest.restoreAllMocks()) + + given('mock', () => jest.fn()) + given('html', () => `
`) + + it('create a Cocooned instance', () => { + jQuery('section:first').cocooned() + + expect(given.mock).toHaveBeenCalled() + }) + + it('forwards options to the Cocooned instance', () => { + const options = { limit: 12 } + jQuery('section:first').cocooned(options) + + expect(given.mock).toHaveBeenCalledWith(document.querySelector('section'), options) + }) + + it('create a Cocooned instance for each member of the jQuery selection', () => { + jQuery('section').cocooned() + + expect(given.mock).toHaveBeenCalledTimes(2) + }) + }) +}) diff --git a/npm/cocooned.js b/npm/cocooned.js index 6d0a4f2..c8c3028 100644 --- a/npm/cocooned.js +++ b/npm/cocooned.js @@ -1,27 +1,9 @@ -import $ from 'jquery' -import { Base } from './src/cocooned/base' -import { limitMixin } from './src/cocooned/plugins/limit' -import { reorderableMixin } from './src/cocooned/plugins/reorderable' -import { CocoonSupportMixin } from './src/integrations/cocoon' -import { jQueryPluginMixin } from './src/integrations/jquery' +import Cocooned from './jquery' +import { deprecator } from './src/cocooned/deprecation' -class Cocooned extends CocoonSupportMixin(reorderableMixin(limitMixin(Base))) { - static create (container, options) { - const cocooned = new Cocooned(container, options) - cocooned.start() - - return cocooned - } - - static start () { - document.querySelectorAll('*[data-cocooned-options]').forEach(element => Cocooned.create(element)) - } -} - -// Expose a jQuery plugin -jQueryPluginMixin($, Cocooned) - -// On-load initialization -$(() => Cocooned.start()) +deprecator('3.0').warn( + 'Loading @notus.sh/cocooned/cocooned is deprecated', + '@notus.sh/cocooned/jquery, @notus.sh/cocooned or @notus.sh/cocooned/src/base' +) export default Cocooned diff --git a/npm/index.js b/npm/index.js new file mode 100644 index 0000000..a6c0884 --- /dev/null +++ b/npm/index.js @@ -0,0 +1,19 @@ +import { Base } from './src/cocooned/base' +import { limitMixin } from './src/cocooned/plugins/limit' +import { reorderableMixin } from './src/cocooned/plugins/reorderable' +import { CocoonSupportMixin } from './src/integrations/cocoon' + +class Cocooned extends CocoonSupportMixin(reorderableMixin(limitMixin(Base))) { + static create (container, options = {}) { + const cocooned = new Cocooned(container, options) + cocooned.start() + + return cocooned + } + + static start () { + document.querySelectorAll('*[data-cocooned-options]').forEach(element => Cocooned.create(element)) + } +} + +export default Cocooned diff --git a/npm/jquery.js b/npm/jquery.js new file mode 100644 index 0000000..81ab92b --- /dev/null +++ b/npm/jquery.js @@ -0,0 +1,15 @@ +/* global jQuery, $ */ +import Cocooned from './index' +import { jQueryPluginMixin } from './src/integrations/jquery' + +// Expose a jQuery plugin +jQueryPluginMixin(jQuery, Cocooned) + +// On-load initialization +const cocoonedAutoStart = () => Cocooned.start() +$(cocoonedAutoStart) + +export default Cocooned +export { + cocoonedAutoStart +} diff --git a/npm/src/cocooned/base.js b/npm/src/cocooned/base.js index a9cace8..f78ed2e 100644 --- a/npm/src/cocooned/base.js +++ b/npm/src/cocooned/base.js @@ -27,6 +27,17 @@ class Base { return ['cocooned'] } + static create (container, options) { + const cocooned = new this.constructor(container, options) + cocooned.start() + + return cocooned + } + + static start () { + document.querySelectorAll('*[data-cocooned-options]').forEach(element => this.constructor.create(element)) + } + constructor (container, options) { this.container = container this.options = this.constructor._normalizeOptions({ diff --git a/package.json b/package.json index 8a3721b..7a0730f 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ }, "devDependencies": { "@faker-js/faker": "^7.6.0", - "@testing-library/jest-dom": "^5.16.5", "eslint": "^8.25.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", @@ -27,7 +26,6 @@ "jest": "^29.1.2", "jest-environment-jsdom": "^29.1.2", "jquery": "^3.0.0", - "jquery-events-to-dom-events": "^1.1.0", "rollup": "^3.7.5" } } diff --git a/yarn.lock b/yarn.lock index 02b70de..927aabf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@adobe/css-tools@^4.0.1": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.1.0.tgz#417fef4a143f4396ad0b3b4351fee21323f15aa8" - integrity sha512-mMVJ/j/GbZ/De4ZHWbQAQO1J6iVnjtZLc9WEdkUQb8S/Bu2cAF2bETXUgMAdvMG3/ngtKmcNBe+Zms9bg6jnQQ== - "@ampproject/remapping@^2.1.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" @@ -264,7 +259,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.19.0" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3": version "7.20.13" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA== @@ -659,21 +654,6 @@ lz-string "^1.4.4" pretty-format "^27.0.2" -"@testing-library/jest-dom@^5.16.5": - version "5.16.5" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e" - integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA== - dependencies: - "@adobe/css-tools" "^4.0.1" - "@babel/runtime" "^7.9.2" - "@types/testing-library__jest-dom" "^5.9.1" - aria-query "^5.0.0" - chalk "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" - lodash "^4.17.15" - redent "^3.0.0" - "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -743,14 +723,6 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*": - version "29.4.0" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.4.0.tgz#a8444ad1704493e84dbf07bb05990b275b3b9206" - integrity sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - "@types/jsdom@^20.0.0": version "20.0.1" resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808" @@ -790,13 +762,6 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/testing-library__jest-dom@^5.9.1": - version "5.14.5" - resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz#d113709c90b3c75fdb127ec338dad7d5f86c974f" - integrity sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ== - dependencies: - "@types/jest" "*" - "@types/tough-cookie@*": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" @@ -1157,14 +1122,6 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -1262,11 +1219,6 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css.escape@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" - integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== - cssom@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" @@ -1394,7 +1346,7 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: +dom-accessibility-api@^0.5.9: version "0.5.16" resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== @@ -1782,7 +1734,7 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expect@^29.0.0, expect@^29.4.1: +expect@^29.4.1: version "29.4.1" resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.1.tgz#58cfeea9cbf479b64ed081fd1e074ac8beb5a1fe" integrity sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A== @@ -2151,11 +2103,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -2786,11 +2733,6 @@ jest@^29.1.2: import-local "^3.0.2" jest-cli "^29.4.1" -jquery-events-to-dom-events@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/jquery-events-to-dom-events/-/jquery-events-to-dom-events-1.1.0.tgz#df038920e05760d9a41e00e2f48ca023f80d5579" - integrity sha512-rEgD7wqslktlvPPlQ74QuaQJ7y33kNCGW0bhAKRiJbSm4yg6xiConpzOqrO2qO5a00hpMQZT7YrSElB7K6o9jg== - jquery@^3.0.0: version "3.6.3" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.3.tgz#23ed2ffed8a19e048814f13391a19afcdba160e6" @@ -2935,11 +2877,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash@^4.17.15: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -3008,11 +2945,6 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -3265,7 +3197,7 @@ pretty-format@^27.0.2: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^29.0.0, pretty-format@^29.4.1: +pretty-format@^29.4.1: version "29.4.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.1.tgz#0da99b532559097b8254298da7c75a0785b1751c" integrity sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg== @@ -3312,14 +3244,6 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - regenerator-runtime@^0.13.11: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" @@ -3569,13 +3493,6 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" From ecc8d2c4134d2a53dc5866ef9e8cf1a5846db2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl-Ian?= Date: Sun, 29 Jan 2023 16:24:33 -0500 Subject: [PATCH 2/2] Remove dependency to jQuery and update documentation --- npm/.npmignore | 2 ++ npm/README.md | 64 ++++++++++++++++++++++++++++---------------- npm/cocooned.css | 1 + npm/package.json.erb | 8 +----- 4 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 npm/.npmignore create mode 100644 npm/cocooned.css diff --git a/npm/.npmignore b/npm/.npmignore new file mode 100644 index 0000000..9c21cda --- /dev/null +++ b/npm/.npmignore @@ -0,0 +1,2 @@ +/__tests__/* +/package.json.erb diff --git a/npm/README.md b/npm/README.md index a7cfa1f..b10e390 100644 --- a/npm/README.md +++ b/npm/README.md @@ -8,8 +8,6 @@ Cocooned is form builder-agnostic: it works with standard Rails (>= 5.0, < 7.0) This package aims to ease cocooned integration with projects that use npm/Yarn to manage non-ruby dependencies and/or use webpacker to build their assets. -Cocooned depends on jQuery, Ruby (>= 2.5) and Rails (>= 5.0, < 7.0). - ## Installation With npm: @@ -26,45 +24,65 @@ You should specify the same version (and version contraints) as in your `Gemfile ## Usage -### With Sprockets +To use Cocooned, import it in one of your JavaScript file with: + +```javascript +import Cocooned from '@notus.sh/cocooned' + +// Detect, create and setup all your Cocooned container at once +Cocooned.start() + +// Or initialize them individually +// Without options +const cocooned = new Cocooned(document.querySelector('a selector to match container')) +// With options +const cocooned = new Cocooned(document.querySelector('a selector to match container'), { limit: 12 }) +``` + +Options can also be provided as a JSON string in a `data-cocooned-options` on your container HTML tag. This is the recommended way to pass options from Ruby-land. + +### Supported options + +* `limit: {Integer}`: Set maximum number of items in your container to the specified limit. +* `reorderable`: Allow items in your container to be reordered (with their respective `position` field updated) + Can be specified as a boolean (`reorderable: true`) or with a `startAt` value updated positions will be counted from (`reorderable: { startAt: 0 }`, defaults to 1) + +For more documentation, please look at the [cocooned Ruby gem](https://rubygems.org/gems/cocooned). + +### Sprockets integration In `config/initializers/assets.rb`, be sure you have something like this: ```ruby Rails.configuration.tap do |config| - # [...] - # Ask Sprockets to load files in ./node_modules config.assets.paths << Rails.root.join('node_modules') - # If you use sass-rails, ask Sass to do the same - config.sass.load_paths << Rails.root.join('node_modules') - - # [...] end ``` -Then load Cocooned with: +Then load Cocooned in one of your JavaScript file with: ```javascript -// In a javascript file //= require '@notus.sh/cocooned/cocooned' -``` -```css -/* In a stylesheet */ -/* - *= require '@notus.sh/cocooned/cocooned' - */ +Cocooned.start() ``` -### With Webpacker +### jQuery integration + +Cocooned does not require jQuery but can integrates with it. ```javascript -// In a javascript file -var Cocooned = require('@notus.sh/cocooned'); +import Cocooned from '@notus.sh/cocooned/jquery' +// Cocooned.start() is already bound on jQuery ready event. ``` -```css -/* In a stylesheet */ -@import '@notus.sh/cocooned/cocooned'; +Once loaded, you can use Cocooned as a jQuery plugin: + +```javascript +// Without options +$('a selector to match container').cocooned() + +// With options +$('a selector to match container').cocooned({ limit: 12 }) ``` diff --git a/npm/cocooned.css b/npm/cocooned.css new file mode 100644 index 0000000..e4e6870 --- /dev/null +++ b/npm/cocooned.css @@ -0,0 +1 @@ +/* Remove in Cocooned 3.0 */ diff --git a/npm/package.json.erb b/npm/package.json.erb index 0eef367..d3a3e8e 100644 --- a/npm/package.json.erb +++ b/npm/package.json.erb @@ -13,11 +13,5 @@ "author": <%= contributors.first.to_json %>, "contributors": <%= contributors.collect { |c| { name: c[:name], email: c[:email] } }.to_json %>, - "browser": true, - "main": "cocooned.js", - "files": ["cocooned.js", "cocooned.css", "README", "LICENSE", "package.json"], - - "dependencies": { - "jquery": "^3.3.1" - } + "browser": true }