From dcd64bf373cb2c7985c2bb224953e66562c3df7e Mon Sep 17 00:00:00 2001 From: Victor Elci Date: Fri, 24 Jan 2025 12:50:01 -0500 Subject: [PATCH 1/4] fix jquery deprecation --- addon/components/ember-jstree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/components/ember-jstree.js b/addon/components/ember-jstree.js index 43e4cc9..166086c 100644 --- a/addon/components/ember-jstree.js +++ b/addon/components/ember-jstree.js @@ -102,7 +102,7 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * @method _setupJsTree */ _setupJsTree() { - return this.$().jstree(this._buildConfig()); + return $(this.element).jstree(this._buildConfig()); }, /** From c061bc062b2fc05b475179c99c9caa7ca22d91ff Mon Sep 17 00:00:00 2001 From: Tyler Bratton Date: Mon, 3 Mar 2025 14:20:48 -0500 Subject: [PATCH 2/4] v3.1.4...v3.28.6 --- .editorconfig | 1 - .eslintignore | 23 +- .eslintrc.js | 61 +-- .gitignore | 32 +- .npmignore | 51 ++- .prettierignore | 22 +- .prettierrc.js | 5 + .template-lintrc.js | 5 + .travis.yml | 58 ++- README.md | 11 +- addon/components/ember-jstree.js | 365 +++++++++--------- config/ember-try.js | 134 ++++--- config/environment.js | 2 +- ember-cli-build.js | 11 +- index.js | 53 +-- package.json | 88 +++-- testem.js | 29 +- tests/dummy/app/app.js | 20 +- tests/dummy/app/resolver.js | 3 - tests/dummy/app/router.js | 18 +- tests/dummy/app/styles/app.css | 2 + tests/dummy/app/templates/application.hbs | 6 +- tests/dummy/app/templates/components/.gitkeep | 0 tests/dummy/config/ember-cli-update.json | 21 + tests/dummy/config/environment.js | 10 +- tests/dummy/config/optional-features.json | 6 + tests/dummy/config/targets.js | 28 +- tests/index.html | 9 +- .../components/ember-jstree-test.js | 176 ++++----- tests/test-helper.js | 12 +- 30 files changed, 726 insertions(+), 536 deletions(-) create mode 100644 .prettierrc.js create mode 100644 .template-lintrc.js delete mode 100644 tests/dummy/app/resolver.js delete mode 100644 tests/dummy/app/templates/components/.gitkeep create mode 100644 tests/dummy/config/ember-cli-update.json create mode 100644 tests/dummy/config/optional-features.json diff --git a/.editorconfig b/.editorconfig index 219985c..c35a002 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,6 @@ root = true - [*] end_of_line = lf charset = utf-8 diff --git a/.eslintignore b/.eslintignore index 0516e6e..701947e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,22 @@ -/blueprints/*/files/**/*.js +# unconventional js +/blueprints/*/files/ +/vendor/ + +# compiled output +/dist/ +/tmp/ + +# dependencies +/bower_components/ +/node_modules/ + +# misc +/coverage/ +!.* +.*/ +.eslintcache + +# ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try diff --git a/.eslintrc.js b/.eslintrc.js index 67d4e50..be97aa2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,52 +1,53 @@ +'use strict'; + module.exports = { root: true, + parser: 'babel-eslint', parserOptions: { - ecmaVersion: 2017, - sourceType: "module" + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + legacyDecorators: true, + }, }, plugins: ["ember", "prettier"], extends: [ - "eslint:recommended", - "plugin:ember/recommended", - "plugin:prettier/recommended" + 'eslint:recommended', + 'plugin:ember/recommended', + 'plugin:prettier/recommended', ], env: { - browser: true + browser: true, }, rules: {}, overrides: [ // node files { files: [ - "ember-cli-build.js", - "index.js", - "testem.js", - "blueprints/*/index.js", - "config/**/*.js", - "tests/dummy/config/**/*.js" - ], - excludedFiles: [ - "addon/**", - "addon-test-support/**", - "app/**", - "tests/dummy/app/**" + './.eslintrc.js', + './.prettierrc.js', + './.template-lintrc.js', + './ember-cli-build.js', + './index.js', + './testem.js', + './blueprints/*/index.js', + './config/**/*.js', + './tests/dummy/config/**/*.js', ], parserOptions: { sourceType: "script", - ecmaVersion: 2015 }, env: { browser: false, - node: true + node: true, }, - plugins: ["node"], - rules: Object.assign( - {}, - require("eslint-plugin-node").configs.recommended.rules, - { - // add your custom rules and overrides for node files here - } - ) - } - ] + plugins: ['node'], + extends: ['plugin:node/recommended'], + }, + { + // Test files: + files: ['tests/**/*-test.{js,ts}'], + extends: ['plugin:qunit/recommended'], + }, + ], }; diff --git a/.gitignore b/.gitignore index e1f96d4..2b688b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,34 @@ # See https://help.github.com/ignore-files/ for more about ignoring files. # compiled output -/dist -/tmp +/dist/ +/tmp/ # dependencies -/node_modules -/bower_components +/bower_components/ +/node_modules/ # misc +/.env* +/.pnp* /.sass-cache +/.eslintcache /connect.lock -/coverage/* +/coverage/ /libpeerconnection.log -npm-debug.log* -yarn-error.log -testem.log +/npm-debug.log* +/testem.log +/yarn-error.log .vscode/ # ember-try -.node_modules.ember-try/ -bower.json.ember-try -package.json.ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try + +.DS_Store +._.DS_Store +**/.DS_Store +**/._.DS_Store + +/.idea diff --git a/.npmignore b/.npmignore index 135c7b1..f30effe 100644 --- a/.npmignore +++ b/.npmignore @@ -1,21 +1,36 @@ -/bower_components +# compiled output +/dist/ +/tmp/ + +# dependencies +/bower_components/ + +# misc +/.bowerrc +/.editorconfig +/.ember-cli +/.env* +/.eslintcache +/.eslintignore +/.eslintrc.js +/.git/ +/.gitignore +/.prettierignore +/.prettierrc.js +/.template-lintrc.js +/.travis.yml +/.watchmanconfig +/bower.json /config/ember-try.js -/dist -/tests -/tmp -**/.gitkeep -.bowerrc -.editorconfig -.ember-cli -.eslintrc.js -.gitignore -.watchmanconfig -.travis.yml -bower.json -ember-cli-build.js -testem.js +/CONTRIBUTING.md +/ember-cli-build.js +/testem.js +/tests/ +/yarn-error.log +/yarn.lock +.gitkeep # ember-try -.node_modules.ember-try/ -bower.json.ember-try -package.json.ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try diff --git a/.prettierignore b/.prettierignore index ec6d3cd..9221655 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,21 @@ -package.json +# unconventional js +/blueprints/*/files/ +/vendor/ + +# compiled output +/dist/ +/tmp/ + +# dependencies +/bower_components/ +/node_modules/ + +# misc +/coverage/ +!.* +.eslintcache + +# ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..534e6d3 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + singleQuote: true, +}; diff --git a/.template-lintrc.js b/.template-lintrc.js new file mode 100644 index 0000000..f35f61c --- /dev/null +++ b/.template-lintrc.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + extends: 'recommended', +}; diff --git a/.travis.yml b/.travis.yml index 49bf551..f3050ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,9 @@ language: node_js node_js: # we recommend testing addons with the same minimum supported node version as Ember CLI # so that your addon works for all apps - - "6" + - "12" -sudo: false -dist: trusty +dist: xenial addons: chrome: stable @@ -20,29 +19,48 @@ env: global: # See https://git.io/vdao3 for details. - JOBS=1 - matrix: - # we recommend new addons test the current and previous LTS - # as well as latest stable release (bonus points to beta/canary) - - EMBER_TRY_SCENARIO=ember-lts-2.12 - - EMBER_TRY_SCENARIO=ember-lts-2.16 - - EMBER_TRY_SCENARIO=ember-lts-2.18 - - EMBER_TRY_SCENARIO=ember-release - - EMBER_TRY_SCENARIO=ember-beta - - EMBER_TRY_SCENARIO=ember-canary - - EMBER_TRY_SCENARIO=ember-default - -matrix: + +branches: + only: + - master + # npm version tags + - /^v\d+\.\d+\.\d+/ + +jobs: fast_finish: true allow_failures: - env: EMBER_TRY_SCENARIO=ember-canary + include: + # runs linting and tests with current locked deps + - stage: "Tests" + name: "Tests" + script: + - yarn lint + - yarn test:ember + + - stage: "Additional Tests" + name: "Floating Dependencies" + install: + - yarn install --no-lockfile --non-interactive + script: + - yarn test:ember + + # we recommend new addons test the current and previous LTS + # as well as latest stable release (bonus points to beta/canary) + - env: EMBER_TRY_SCENARIO=ember-lts-3.24 + - env: EMBER_TRY_SCENARIO=ember-lts-3.28 + - env: EMBER_TRY_SCENARIO=ember-release + - env: EMBER_TRY_SCENARIO=ember-beta + - env: EMBER_TRY_SCENARIO=ember-canary + - env: EMBER_TRY_SCENARIO=ember-default-with-jquery + - env: EMBER_TRY_SCENARIO=ember-classic + - env: EMBER_TRY_SCENARIO=embroider-safe + - env: EMBER_TRY_SCENARIO=embroider-optimized + before_install: - curl -o- -L https://yarnpkg.com/install.sh | bash - export PATH=$HOME/.yarn/bin:$PATH -install: - - yarn install --no-lockfile --non-interactive - script: - - yarn lint:js - - yarn ember try:one $EMBER_TRY_SCENARIO --skip-cleanup + - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO diff --git a/README.md b/README.md index 5c60d2f..ebfbf50 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,16 @@ Brings [jsTree](http://www.jstree.com/) functionality into your Ember app. Demo: http://ritesh83.github.io/ember-cli-jstree/#/static -## Installation +Compatibility +------------------------------------------------------------------------------ -Ember CLI addons can be installed with `ember install` +* Ember.js v3.24 or above +* Ember CLI v3.24 or above +* Node.js v12 or above + + +Installation +------------------------------------------------------------------------------ ``` ember install ember-cli-jstree diff --git a/addon/components/ember-jstree.js b/addon/components/ember-jstree.js index 166086c..3ceb634 100644 --- a/addon/components/ember-jstree.js +++ b/addon/components/ember-jstree.js @@ -1,13 +1,13 @@ -import Ember from "ember"; -import Component from "@ember/component"; -import InboundActions from "ember-component-inbound-actions/inbound-actions"; -import EmberJstreeActions from "ember-cli-jstree/mixins/ember-jstree-actions"; -import { registerWaiter, unregisterWaiter } from "@ember/test"; -import { observer } from "@ember/object"; -import { isPresent, typeOf } from "@ember/utils"; -import { A } from "@ember/array"; -import $ from "jquery"; -import { next, schedule } from "@ember/runloop"; +import Ember from 'ember'; +import Component from '@ember/component'; +import InboundActions from 'ember-component-inbound-actions/inbound-actions'; +import EmberJstreeActions from 'ember-cli-jstree/mixins/ember-jstree-actions'; +import { registerWaiter, unregisterWaiter } from '@ember/test'; +import { observer } from '@ember/object'; +import { isPresent, typeOf } from '@ember/utils'; +import { A } from '@ember/array'; +import jQuery from 'jquery'; +import { next, schedule } from '@ember/runloop'; const { testing } = Ember; @@ -47,11 +47,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { _searchTerm: null, _isReadyTestWaiter() { - return this.get("isReady") === true; + return this.isReady === true; }, didInsertElement() { - schedule("afterRender", this, this.createTree); + this._super(...arguments); + schedule('afterRender', this, this.createTree); }, createTree() { @@ -64,30 +65,31 @@ export default Component.extend(InboundActions, EmberJstreeActions, { this._setupEventHandlers(treeObject); - this.set("treeObject", treeObject); + this.set('treeObject', treeObject); }, willDestroyElement() { + this._super(...arguments); if (testing) { unregisterWaiter(this, this._isReadyTestWaiter); } - this.set("isReady", false); - this.set("_isDestroying", true); - this.send("destroy"); + this.set('isReady', false); + this.set('_isDestroying', true); + this.send('destroy'); }, didUpdateAttrs() { this._super(...arguments); - let pluginsArray = this.get("plugins"); + let pluginsArray = this.plugins; if (isPresent(pluginsArray)) { - let searchOptions = this.get("searchOptions"); - if (isPresent(searchOptions) && pluginsArray.indexOf("search") >= 0) { - let searchTerm = this.get("searchTerm"); - if (this.get("_searchTerm") !== searchTerm) { - next("afterRender", () => { - this.set("_searchTerm", searchTerm); + let searchOptions = this.searchOptions; + if (isPresent(searchOptions) && pluginsArray.indexOf('search') >= 0) { + let searchTerm = this.searchTerm; + if (this._searchTerm !== searchTerm) { + next('afterRender', () => { + this.set('_searchTerm', searchTerm); this.getTree().search(searchTerm); }); } @@ -102,7 +104,7 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * @method _setupJsTree */ _setupJsTree() { - return $(this.element).jstree(this._buildConfig()); + return jQuery(this.element).jstree(this._buildConfig()); }, /** @@ -113,71 +115,70 @@ export default Component.extend(InboundActions, EmberJstreeActions, { _buildConfig() { let configObject = {}; - configObject["core"] = { - data: this.get("data"), - check_callback: this.get("checkCallback"), - multiple: this.get("multiple"), - worker: this.get("worker") + configObject['core'] = { + data: this.data, + check_callback: this.checkCallback, + multiple: this.multiple, + worker: this.worker, }; - let themes = this.get("themes"); - if (isPresent(themes) && typeOf(themes) === "object") { - configObject["core"]["themes"] = themes; + let themes = this.themes; + if (isPresent(themes) && typeOf(themes) === 'object') { + configObject['core']['themes'] = themes; } - let pluginsArray = this.get("plugins"); + let pluginsArray = this.plugins; if (isPresent(pluginsArray)) { - pluginsArray = pluginsArray.replace(/ /g, "").split(","); - configObject["plugins"] = pluginsArray; + pluginsArray = pluginsArray.replace(/ /g, '').split(','); + configObject['plugins'] = pluginsArray; if ( - pluginsArray.includes("contextmenu") || - pluginsArray.includes("dnd") || - pluginsArray.includes("unique") + pluginsArray.includes('contextmenu') || + pluginsArray.includes('dnd') || + pluginsArray.includes('unique') ) { // These plugins need core.check_callback - configObject["core"]["check_callback"] = - configObject["core"]["check_callback"] || true; + configObject['core']['check_callback'] = + configObject['core']['check_callback'] || true; } - let checkboxOptions = this.get("checkboxOptions"); - if (isPresent(checkboxOptions) && pluginsArray.includes("checkbox")) { - configObject["checkbox"] = checkboxOptions; + let checkboxOptions = this.checkboxOptions; + if (isPresent(checkboxOptions) && pluginsArray.includes('checkbox')) { + configObject['checkbox'] = checkboxOptions; } - let searchOptions = this.get("searchOptions"); - if (isPresent(searchOptions) && pluginsArray.includes("search")) { - configObject["search"] = searchOptions; + let searchOptions = this.searchOptions; + if (isPresent(searchOptions) && pluginsArray.includes('search')) { + configObject['search'] = searchOptions; } - let sort = this.get("sort"); - if (isPresent(sort) && pluginsArray.includes("sort")) { - configObject["sort"] = sort; + let sort = this.sort; + if (isPresent(sort) && pluginsArray.includes('sort')) { + configObject['sort'] = sort; } - let stateOptions = this.get("stateOptions"); - if (isPresent(stateOptions) && pluginsArray.includes("state")) { - configObject["state"] = stateOptions; + let stateOptions = this.stateOptions; + if (isPresent(stateOptions) && pluginsArray.includes('state')) { + configObject['state'] = stateOptions; } - let typesOptions = this.get("typesOptions"); - if (isPresent(typesOptions) && pluginsArray.includes("types")) { - configObject["types"] = typesOptions; + let typesOptions = this.typesOptions; + if (isPresent(typesOptions) && pluginsArray.includes('types')) { + configObject['types'] = typesOptions; } - let contextmenuOptions = this.get("contextmenuOptions"); + let contextmenuOptions = this.contextmenuOptions; if ( isPresent(contextmenuOptions) && - pluginsArray.includes("contextmenu") + pluginsArray.includes('contextmenu') ) { - configObject["contextmenu"] = this._setupContextMenus( - contextmenuOptions - ); + configObject['contextmenu'] = + this._setupContextMenus(contextmenuOptions); } - let dndOptions = this.get("dndOptions"); - if (isPresent(dndOptions) && pluginsArray.includes("dnd")) { - configObject["dnd"] = dndOptions; + let dndOptions = this.dndOptions; + if (isPresent(dndOptions) && pluginsArray.includes('dnd')) { + configObject['dnd'] = dndOptions; } } @@ -192,25 +193,25 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * @return {Array} An Array of Ember-friendly options to pass back into the config object */ _setupContextMenus(contextmenuOptions) { - if (typeOf(contextmenuOptions["items"]) === "object") { + if (typeOf(contextmenuOptions['items']) === 'object') { let newMenuItems = {}; - let menuItems = Object.keys(contextmenuOptions["items"]); + let menuItems = Object.keys(contextmenuOptions['items']); for (let menuItem of menuItems) { - let itemData = contextmenuOptions["items"][menuItem]; + let itemData = contextmenuOptions['items'][menuItem]; newMenuItems[menuItem] = itemData; // Only change if not a function // This needs to be done to handle Ember actions - if (typeOf(itemData["action"]) !== "function") { - let emberAction = itemData["action"]; + if (typeOf(itemData['action']) !== 'function') { + let emberAction = itemData['action']; - newMenuItems[menuItem]["action"] = data => { - this.send("contextmenuItemDidClick", emberAction, data); + newMenuItems[menuItem]['action'] = (data) => { + this.send('contextmenuItemDidClick', emberAction, data); }; } } - contextmenuOptions["items"] = newMenuItems; + contextmenuOptions['items'] = newMenuItems; } return contextmenuOptions; @@ -225,9 +226,9 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * @return */ _setupEventHandlers(treeObject) { - if (typeof treeObject !== "object") { + if (typeof treeObject !== 'object') { throw new Error( - "You must pass a valid jsTree object to set up its event handlers" + 'You must pass a valid jsTree object to set up its event handlers' ); } @@ -236,12 +237,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidInit triggered after all events are bound */ - treeObject.on("init.jstree", () => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('init.jstree', () => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidInit"); + this.callAction('eventDidInit'); }); }); @@ -250,12 +251,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventIsLoading triggered after the loading text is shown and before loading starts */ - treeObject.on("loading.jstree", () => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('loading.jstree', () => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventIsLoading"); + this.callAction('eventIsLoading'); }); }); @@ -264,12 +265,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidLoad triggered after the root node is loaded for the first time */ - treeObject.on("loaded.jstree", () => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('loaded.jstree', () => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidLoad"); + this.callAction('eventDidLoad'); }); }); @@ -278,13 +279,13 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidBecomeReady triggered after all nodes are finished loading */ - treeObject.on("ready.jstree", () => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('ready.jstree', () => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.set("isReady", true); - this.callAction("eventDidBecomeReady"); + this.set('isReady', true); + this.callAction('eventDidBecomeReady'); }); }); @@ -293,12 +294,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidRedraw triggered after nodes are redrawn */ - treeObject.on("redraw.jstree", () => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('redraw.jstree', () => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidRedraw"); + this.callAction('eventDidRedraw'); }); }); @@ -307,12 +308,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidOpen triggered when a node is opened and the animation is complete */ - treeObject.on("after_open.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('after_open.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidOpen", data.node); + this.callAction('eventDidOpen', data.node); }); }); @@ -321,12 +322,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidClose triggered when a node is closed and the animation is complete */ - treeObject.on("after_close.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('after_close.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidClose", data.node); + this.callAction('eventDidClose', data.node); }); }); @@ -335,13 +336,13 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidSelectNode triggered when an node is selected */ - treeObject.on("select_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('select_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } this.callAction( - "eventDidSelectNode", + 'eventDidSelectNode', data.node, data.selected, data.event @@ -354,13 +355,13 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidDeselectNode triggered when an node is deselected */ - treeObject.on("deselect_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('deselect_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } this.callAction( - "eventDidDeselectNode", + 'eventDidDeselectNode', data.node, data.selected, data.event @@ -373,35 +374,31 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: jstreeDidChange triggered when selection changes */ - treeObject.on("changed.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('changed.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } // Check if selection changed - if (isPresent(this.get("treeObject"))) { + if (isPresent(this.treeObject)) { let selectionChangedEventNames = [ - "model", - "select_node", - "deselect_node", - "select_all", - "deselect_all" + 'model', + 'select_node', + 'deselect_node', + 'select_all', + 'deselect_all', ]; if ( isPresent(data.action) && selectionChangedEventNames.includes(data.action) ) { - let selNodes = A( - this.get("treeObject") - .jstree(true) - .get_selected(true) - ); - this.set("selectedNodes", selNodes); + let selNodes = A(this.treeObject.jstree(true).get_selected(true)); + this.set('selectedNodes', selNodes); } } - this.callAction("eventDidChange", data); + this.callAction('eventDidChange', data); }); }); @@ -410,12 +407,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidHoverNode triggered when a node is hovered */ - treeObject.on("hover_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('hover_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidHoverNode", data.node); + this.callAction('eventDidHoverNode', data.node); }); }); @@ -424,12 +421,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidDehoverNode triggered when a node is no longer hovered */ - treeObject.on("dehover_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('dehover_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidDehoverNode", data.node); + this.callAction('eventDidDehoverNode', data.node); }); }); @@ -438,12 +435,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidShowNode triggered when a node is no longer hovered */ - treeObject.on("show_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('show_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidShowNode", data.node); + this.callAction('eventDidShowNode', data.node); }); }); @@ -452,45 +449,45 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidMoveNode triggered when a node is moved */ - treeObject.on("move_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('move_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidMoveNode", data); + this.callAction('eventDidMoveNode', data); }); }); - let pluginsArray = this.get("plugins"); + let pluginsArray = this.plugins; - if (isPresent(pluginsArray) && pluginsArray.indexOf("search") > -1) { + if (isPresent(pluginsArray) && pluginsArray.indexOf('search') > -1) { /* Event: search.jstree Action: eventDidSearch triggered when a search action is performed */ - treeObject.on("search.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('search.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidSearch", event, data); + this.callAction('eventDidSearch', event, data); }); }); } - if (isPresent(pluginsArray) && pluginsArray.indexOf("checkbox") > -1) { + if (isPresent(pluginsArray) && pluginsArray.indexOf('checkbox') > -1) { /* Event: disable_checkbox.jstree Action: eventDidDisableCheckbox triggered when an node's checkbox is disabled */ - treeObject.on("disable_checkbox.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('disable_checkbox.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidDisableCheckbox", data.node); + this.callAction('eventDidDisableCheckbox', data.node); }); }); @@ -499,31 +496,31 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidEnableCheckbox triggered when an node's checkbox is enabled */ - treeObject.on("enable_checkbox.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('enable_checkbox.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidEnableCheckbox", data.node); + this.callAction('eventDidEnableCheckbox', data.node); }); }); if ( - isPresent("checkboxOptions.tie_selected") && - !this.get("checkboxOptions.tie_selected") + isPresent('checkboxOptions.tie_selected') && + !this.get('checkboxOptions.tie_selected') ) { /* Event: check_node.jstree Action: eventDidCheckNode triggered when an node is checked (only if tie_selection in checkbox settings is false) */ - treeObject.on("check_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('check_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } this.callAction( - "eventDidCheckNode", + 'eventDidCheckNode', data.node, data.selected, data.event @@ -536,13 +533,13 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidUncheckNode triggered when an node is unchecked (only if tie_selection in checkbox settings is false) */ - treeObject.on("uncheck_node.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('uncheck_node.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } this.callAction( - "eventDidUncheckNode", + 'eventDidUncheckNode', data.node, data.selected, data.event @@ -555,12 +552,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidCheckAll triggered when all nodes are checked (only if tie_selection in checkbox settings is false) */ - treeObject.on("check_all.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('check_all.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidCheckAll", data.selected); + this.callAction('eventDidCheckAll', data.selected); }); }); @@ -569,12 +566,12 @@ export default Component.extend(InboundActions, EmberJstreeActions, { Action: eventDidUncheckAll triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) */ - treeObject.on("uncheck_all.jstree", (event, data) => { - next(this, function() { - if (this.get("isDestroyed") || this.get("isDestroying")) { + treeObject.on('uncheck_all.jstree', (event, data) => { + next(this, function () { + if (this.isDestroyed || this.isDestroying) { return; } - this.callAction("eventDidUncheckAll", data.node, data.selected); + this.callAction('eventDidUncheckAll', data.node, data.selected); }); }); } @@ -587,32 +584,32 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * * @method _redrawTree */ - _refreshTree: observer("data", function() { + _refreshTree: observer('data', function () { let tree = this.getTree(); if (null !== tree && false !== tree) { - tree.settings.core["data"] = this.get("data"); - tree.refresh(this.get("skipLoading"), this.get("forgetState")); + tree.settings.core['data'] = this.data; + tree.refresh(this.skipLoading, this.forgetState); } else { // setup again if destroyed let treeObject = this._setupJsTree(); this._setupEventHandlers(treeObject); - this.set("treeObject", treeObject); + this.set('treeObject', treeObject); } }), getTree() { - let tree = this.get("treeObject"); + let tree = this.treeObject; return tree.jstree(true); }, actions: { contextmenuItemDidClick(actionName, data) { - let emberTreeObj = this.get("getTree"); + let emberTreeObj = this.getTree; - let instance = $.jstree.reference(data.reference); + let instance = jQuery.jstree.reference(data.reference); let node = instance.get_node(data.reference); this.callAction(actionName, node, emberTreeObj); - } - } + }, + }, }); diff --git a/config/ember-try.js b/config/ember-try.js index 20105ab..ad0d729 100644 --- a/config/ember-try.js +++ b/config/ember-try.js @@ -1,71 +1,85 @@ "use strict"; const getChannelURL = require("ember-source-channel-url"); +const { embroiderSafe, embroiderOptimized } = require('@embroider/test-setup'); -module.exports = function() { - return Promise.all([ - getChannelURL("release"), - getChannelURL("beta"), - getChannelURL("canary") - ]).then(urls => { - return { - useYarn: true, - scenarios: [ - { - name: "ember-lts-2.12", - npm: { - devDependencies: { - "ember-source": "~2.12.0" - } - } +module.exports = async function () { + return { + useYarn: true, + scenarios: [ + { + name: 'ember-lts-3.24', + npm: { + devDependencies: { + 'ember-source': '~3.24.3', + }, }, - { - name: "ember-lts-2.16", - npm: { - devDependencies: { - "ember-source": "~2.16.0" - } - } + }, + { + name: 'ember-lts-3.28', + npm: { + devDependencies: { + 'ember-source': '~3.28.0', + }, }, - { - name: "ember-lts-2.18", - npm: { - devDependencies: { - "ember-source": "~2.18.0" - } - } + }, + { + name: "ember-release", + npm: { + devDependencies: { + "ember-source": await getChannelURL('release'), + }, }, - { - name: "ember-release", - npm: { - devDependencies: { - "ember-source": urls[0] - } - } + }, + { + name: "ember-beta", + npm: { + devDependencies: { + "ember-source": await getChannelURL('beta'), + }, }, - { - name: "ember-beta", - npm: { - devDependencies: { - "ember-source": urls[1] - } - } + }, + { + name: "ember-canary", + npm: { + devDependencies: { + "ember-source": await getChannelURL('canary'), + }, }, - { - name: "ember-canary", - npm: { - devDependencies: { - "ember-source": urls[2] - } - } + }, + { + name: 'ember-default-with-jquery', + env: { + EMBER_OPTIONAL_FEATURES: JSON.stringify({ + 'jquery-integration': true, + }), }, - { - name: "ember-default", - npm: { - devDependencies: {} - } - } - ] - }; - }); + npm: { + devDependencies: { + '@ember/jquery': '^1.1.0', + }, + }, + }, + { + name: 'ember-classic', + env: { + EMBER_OPTIONAL_FEATURES: JSON.stringify({ + 'application-template-wrapper': true, + 'default-async-observers': false, + 'template-only-glimmer-components': false, + }), + }, + npm: { + devDependencies: { + 'ember-source': '~3.28.0', + }, + ember: { + edition: 'classic', + }, + }, + }, + embroiderSafe(), + embroiderOptimized(), + ], + }; }; diff --git a/config/environment.js b/config/environment.js index 352093f..b723858 100644 --- a/config/environment.js +++ b/config/environment.js @@ -1,5 +1,5 @@ "use strict"; -module.exports = function(/* environment, appConfig */) { +module.exports = function (/* environment, appConfig */) { return {}; }; diff --git a/ember-cli-build.js b/ember-cli-build.js index fc609dd..4689674 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -2,7 +2,7 @@ const EmberAddon = require("ember-cli/lib/broccoli/ember-addon"); -module.exports = function(defaults) { +module.exports = function (defaults) { let app = new EmberAddon(defaults, { "ember-bootstrap": { importBootstrapTheme: true, @@ -19,5 +19,12 @@ module.exports = function(defaults) { behave. You most likely want to be modifying `./index.js` or app's build file */ - return app.toTree(); + const { maybeEmbroider } = require('@embroider/test-setup'); + return maybeEmbroider(app, { + skipBabel: [ + { + package: 'qunit', + }, + ], + }); }; diff --git a/index.js b/index.js index 6000638..91fd4e6 100644 --- a/index.js +++ b/index.js @@ -1,16 +1,16 @@ -"use strict"; +'use strict'; -const mergeTrees = require("broccoli-merge-trees"); -const Funnel = require("broccoli-funnel"); -const path = require("path"); -const version = require("./package.json").version; -const writeFile = require("broccoli-file-creator"); +const mergeTrees = require('broccoli-merge-trees'); +const Funnel = require('broccoli-funnel'); +const path = require('path'); +const version = require('./package.json').version; +const writeFile = require('broccoli-file-creator'); module.exports = { - name: "ember-cli-jstree", + name: require('./package').name, _jstreePath() { - return path.dirname(require.resolve("jstree/package.json")); + return path.dirname(require.resolve('jstree/package.json')); }, included(app) { @@ -20,38 +20,43 @@ module.exports = { return; } - app.import("vendor/ember-cli-jstree/jstree.js"); - app.import("vendor/ember-cli-jstree/style.css"); - app.import("vendor/ember-cli-jstree/register-version.js"); + app.import('vendor/ember-cli-jstree/jstree.js'); + app.import('vendor/ember-cli-jstree/style.css'); + app.import('vendor/ember-cli-jstree/register-version.js'); }, treeForVendor(tree) { let registerVersionTree = writeFile( - "ember-cli-jstree/register-version.js", + 'ember-cli-jstree/register-version.js', `Ember.libraries.register('Ember CLI jsTree', '${version}')` ); let stylesTree = new Funnel( - path.join(this._jstreePath(), "dist/themes/default"), + path.join(this._jstreePath(), 'dist/themes/default'), { - include: ["*.css"], - destDir: "ember-cli-jstree" + include: ['*.css'], + destDir: 'ember-cli-jstree', } ); - let jsTree = new Funnel(path.join(this._jstreePath(), "dist"), { - include: ["*.js"], - destDir: "ember-cli-jstree" + let jsTree = new Funnel(path.join(this._jstreePath(), 'dist'), { + include: ['*.js'], + destDir: 'ember-cli-jstree', }); - - return tree ? mergeTrees([tree, registerVersionTree, jsTree, stylesTree], {overwrite: true}) : mergeTrees([registerVersionTree, jsTree, stylesTree], {overwrite: true}); + return tree + ? mergeTrees([tree, registerVersionTree, jsTree, stylesTree], { + overwrite: true, + }) + : mergeTrees([registerVersionTree, jsTree, stylesTree], { + overwrite: true, + }); }, treeForPublic() { - return new Funnel(path.join(this._jstreePath(), "dist/themes/default"), { - include: ["**/*.png", "**/*.gif"], - destDir: "/assets" + return new Funnel(path.join(this._jstreePath(), 'dist/themes/default'), { + include: ['**/*.png', '**/*.gif'], + destDir: '/assets', }); - } + }, }; diff --git a/package.json b/package.json index a8b27f2..23c9f7b 100644 --- a/package.json +++ b/package.json @@ -7,50 +7,65 @@ "test": "tests" }, "scripts": { - "build": "ember build", - "lint:js": "eslint ./*.js addon addon-test-support app blueprints config lib server test-support tests", + "build": "ember build --environment=production", + "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"", + "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix", + "lint:hbs": "ember-template-lint .", + "lint:hbs:fix": "ember-template-lint . --fix", + "lint:js": "eslint . --cache", + "lint:js:fix": "eslint . --fix", "start": "ember serve", - "test": "ember test", - "test:all": "ember try:each" + "test": "npm-run-all lint test:*", + "test:ember": "ember test", + "test:ember-compatibility": "ember try:each" }, "repository": { "type": "git", "url": "git://github.com/ritesh83/ember-cli-jstree.git" }, "engines": { - "node": "^4.5 || 6.* || >= 7.*" + "node": "12.* || 14.* || >= 16" }, "author": "", "license": "MIT", "devDependencies": { - "bootstrap": "^3.3.7", - "broccoli-asset-rev": "^2.4.5", - "ember-bootstrap": "^1.2.2", - "ember-cli": "~3.1.4", - "ember-cli-dependency-checker": "^2.0.0", - "ember-cli-eslint": "^4.2.1", + "@ember/optional-features": "^2.0.0", + "@ember/test-helpers": "^2.6.0", + "@embroider/test-setup": "^0.48.1", + "@glimmer/component": "^1.0.4", + "@glimmer/tracking": "^1.0.4", + "babel-eslint": "^10.1.0", + "bootstrap": "^3.4.1", + "broccoli-asset-rev": "^3.0.0", + "ember-auto-import": "^1.12.0", + "ember-cli": "~3.28.6", + "ember-cli-dependency-checker": "^3.2.0", "ember-cli-github-pages": "^0.2.0", - "ember-cli-htmlbars": "^2.0.1", - "ember-cli-htmlbars-inline-precompile": "^1.0.0", - "ember-cli-inject-live-reload": "^1.4.1", - "ember-cli-qunit": "^4.1.1", - "ember-cli-shims": "^1.2.0", - "ember-cli-sri": "^2.1.0", - "ember-cli-uglify": "^2.0.0", - "ember-disable-prototype-extensions": "^1.1.2", - "ember-export-application-global": "^2.0.0", - "ember-load-initializers": "^1.0.0", + "ember-cli-inject-live-reload": "^2.1.0", + "ember-cli-sri": "^2.1.1", + "ember-cli-terser": "^4.0.2", + "ember-disable-prototype-extensions": "^1.1.3", + "ember-export-application-global": "^2.0.1", + "ember-load-initializers": "^2.1.2", "ember-maybe-import-regenerator": "^0.1.6", - "ember-resolver": "^4.0.0", - "ember-source": "~3.1.0", - "ember-source-channel-url": "^1.0.1", - "ember-try": "^0.2.23", - "eslint-config-prettier": "^2.9.0", - "eslint-plugin-ember": "^5.0.0", - "eslint-plugin-node": "^6.0.1", - "eslint-plugin-prettier": "^2.6.0", - "loader.js": "^4.2.3", - "prettier": "^1.12.1" + "ember-page-title": "^6.2.2", + "ember-qunit": "^5.1.5", + "ember-resolver": "^8.0.3", + "ember-source": "~3.28.8", + "ember-source-channel-url": "^3.0.0", + "ember-template-lint": "^3.15.0", + "ember-try": "^1.4.0", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-ember": "^10.5.8", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-qunit": "^6.2.0", + "loader.js": "^4.7.0", + "npm-run-all": "^4.1.5", + "prettier": "^2.5.1", + "qunit": "^2.17.2", + "qunit-dom": "^1.6.0" }, "keywords": [ "ember-addon", @@ -59,13 +74,18 @@ "jquery" ], "dependencies": { + "@ember/jquery": "^2.0.0", "broccoli-file-creator": "^2.1.1", - "broccoli-funnel": "^2.0.1", - "broccoli-merge-trees": "^3.0.0", - "ember-cli-babel": "^6.6.0", + "broccoli-funnel": "^3.0.8", + "broccoli-merge-trees": "^4.2.0", + "ember-cli-babel": "^7.26.10", + "ember-cli-htmlbars": "^5.7.2", "ember-component-inbound-actions": "^1.2.1", "jstree": "^3.3.5" }, + "ember": { + "edition": "octane" + }, "ember-addon": { "configPath": "tests/dummy/config", "demoURL": "http://ritesh83.github.io/ember-cli-jstree/#/static" diff --git a/testem.js b/testem.js index 498413f..b1d3806 100644 --- a/testem.js +++ b/testem.js @@ -1,20 +1,23 @@ +'use strict'; + module.exports = { test_page: "tests/index.html?hidepassed", disable_watching: true, - launch_in_ci: ["Chrome"], - launch_in_dev: ["Chrome"], + launch_in_ci: ['Chrome'], + launch_in_dev: ['Chrome'], + browser_start_timeout: 120, browser_args: { Chrome: { - mode: "ci", - args: [ + ci: [ // --no-sandbox is needed when running Chrome inside a container - process.env.TRAVIS ? "--no-sandbox" : null, - - "--disable-gpu", - "--headless", - "--remote-debugging-port=0", - "--window-size=1440,900" - ].filter(Boolean) - } - } + process.env.CI ? '--no-sandbox' : null, + '--headless', + '--disable-dev-shm-usage', + '--disable-software-rasterizer', + '--mute-audio', + '--remote-debugging-port=0', + '--window-size=1440,900', + ].filter(Boolean), + }, + }, }; diff --git a/tests/dummy/app/app.js b/tests/dummy/app/app.js index e2fb6a8..523bad6 100644 --- a/tests/dummy/app/app.js +++ b/tests/dummy/app/app.js @@ -1,14 +1,12 @@ -import Application from "@ember/application"; -import Resolver from "./resolver"; -import loadInitializers from "ember-load-initializers"; -import config from "./config/environment"; +import Application from '@ember/application'; +import Resolver from 'ember-resolver'; +import loadInitializers from 'ember-load-initializers'; +import config from 'dummy/config/environment'; -const App = Application.extend({ - modulePrefix: config.modulePrefix, - podModulePrefix: config.podModulePrefix, - Resolver -}); +export default class App extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; +} loadInitializers(App, config.modulePrefix); - -export default App; diff --git a/tests/dummy/app/resolver.js b/tests/dummy/app/resolver.js deleted file mode 100644 index fbc2b73..0000000 --- a/tests/dummy/app/resolver.js +++ /dev/null @@ -1,3 +0,0 @@ -import Resolver from "ember-resolver"; - -export default Resolver; diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index f007b5b..01aa7c0 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -1,12 +1,12 @@ -import EmberRouter from "@ember/routing/router"; -import config from "./config/environment"; +import EmberRouter from '@ember/routing/router'; +import config from 'dummy/config/environment'; -const Router = EmberRouter.extend({ - location: config.locationType, - rootURL: config.rootURL -}); +export default class Router extends EmberRouter { + location = config.locationType; + rootURL = config.rootURL; +} -export default Router.map(function() { - this.route("dynamic"); - this.route("static"); +Router.map(function () { + this.route('static'); + this.route('dynamic'); }); diff --git a/tests/dummy/app/styles/app.css b/tests/dummy/app/styles/app.css index 284d4fe..290fb07 100644 --- a/tests/dummy/app/styles/app.css +++ b/tests/dummy/app/styles/app.css @@ -1,3 +1,5 @@ +@import 'bootstrap'; + body, html { font-size: 0.9em; diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs index 4fd52c9..60e35fd 100644 --- a/tests/dummy/app/templates/application.hbs +++ b/tests/dummy/app/templates/application.hbs @@ -1,6 +1,6 @@ -
-

Ember CLI jsTree

-
+{{page-title "Dummy"}} + +

Ember CLI jsTree

Examples

diff --git a/tests/dummy/app/templates/components/.gitkeep b/tests/dummy/app/templates/components/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/dummy/config/ember-cli-update.json b/tests/dummy/config/ember-cli-update.json new file mode 100644 index 0000000..13acfdb --- /dev/null +++ b/tests/dummy/config/ember-cli-update.json @@ -0,0 +1,21 @@ +{ + "schemaVersion": "1.0.0", + "packages": [ + { + "name": "ember-cli", + "version": "3.28.6", + "blueprints": [ + { + "name": "addon", + "outputRepo": "https://github.com/ember-cli/ember-addon-output", + "codemodsSource": "ember-addon-codemods-manifest@1", + "isBaseBlueprint": true, + "options": [ + "--yarn", + "--no-welcome" + ] + } + ] + } + ] +} diff --git a/tests/dummy/config/environment.js b/tests/dummy/config/environment.js index a1c80ce..f3fee60 100644 --- a/tests/dummy/config/environment.js +++ b/tests/dummy/config/environment.js @@ -1,6 +1,6 @@ "use strict"; -module.exports = function(environment) { +module.exports = function (environment) { let ENV = { modulePrefix: "dummy", environment, @@ -9,18 +9,18 @@ module.exports = function(environment) { EmberENV: { FEATURES: { // Here you can enable experimental features on an ember canary build - // e.g. 'with-controller': true + // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true }, EXTEND_PROTOTYPES: { // Prevent Ember Data from overriding Date.parse. - Date: false - } + Date: false, + }, }, APP: { // Here you can pass flags/options to your application instance // when it is created - } + }, }; if (environment === "development") { diff --git a/tests/dummy/config/optional-features.json b/tests/dummy/config/optional-features.json new file mode 100644 index 0000000..b26286e --- /dev/null +++ b/tests/dummy/config/optional-features.json @@ -0,0 +1,6 @@ +{ + "application-template-wrapper": false, + "default-async-observers": true, + "jquery-integration": false, + "template-only-glimmer-components": true +} diff --git a/tests/dummy/config/targets.js b/tests/dummy/config/targets.js index cfd311d..3406036 100644 --- a/tests/dummy/config/targets.js +++ b/tests/dummy/config/targets.js @@ -1,18 +1,26 @@ "use strict"; const browsers = [ - "last 1 Chrome versions", - "last 1 Firefox versions", - "last 1 Safari versions" + 'last 1 Chrome versions', + 'last 1 Firefox versions', + 'last 1 Safari versions', ]; -const isCI = !!process.env.CI; -const isProduction = process.env.EMBER_ENV === "production"; - -if (isCI || isProduction) { - browsers.push("ie 11"); -} +// Ember's browser support policy is changing, and IE11 support will end in +// v4.0 onwards. +// +// See https://deprecations.emberjs.com/v3.x#toc_3-0-browser-support-policy +// +// If you need IE11 support on a version of Ember that still offers support +// for it, uncomment the code block below. +// +// const isCI = Boolean(process.env.CI); +// const isProduction = process.env.EMBER_ENV === "production"; +// +// if (isCI || isProduction) { +// browsers.push("ie 11"); +// } module.exports = { - browsers + browsers, }; diff --git a/tests/index.html b/tests/index.html index 5209b85..6d13069 100644 --- a/tests/index.html +++ b/tests/index.html @@ -21,7 +21,14 @@ {{content-for "body"}} {{content-for "test-body"}} - +
+
+
+
+
+
+ + diff --git a/tests/integration/components/ember-jstree-test.js b/tests/integration/components/ember-jstree-test.js index 9755fab..f810f5f 100644 --- a/tests/integration/components/ember-jstree-test.js +++ b/tests/integration/components/ember-jstree-test.js @@ -1,19 +1,19 @@ -import { module, test } from "qunit"; -import { setupRenderingTest } from "ember-qunit"; -import { render, find } from "@ember/test-helpers"; -import hbs from "htmlbars-inline-precompile"; -import $ from "jquery"; +import { render, find } from '@ember/test-helpers'; +import { setupRenderingTest } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; +import jQuery from 'jquery'; +import { module, test } from 'qunit'; -module("Integration | Component | ember-jstree", function(hooks) { +module('Integration | Component | ember-jstree', function (hooks) { setupRenderingTest(hooks); - test("events#eventDidOpen", async function(assert) { + test('events#eventDidOpen', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidOpen(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -23,17 +23,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("after_open.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('after_open.jstree', data); }); - test("events#eventDidClose", async function(assert) { + test('events#eventDidClose', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidClose(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -43,17 +43,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("after_close.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('after_close.jstree', data); }); - test("events#eventDidChange", async function(assert) { + test('events#eventDidChange', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidChange(e) { assert.equal(e, data); - } + }, }); await render(hbs` @@ -63,17 +63,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("changed.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('changed.jstree', data); }); - test("events#eventDidDehoverNode", async function(assert) { + test('events#eventDidDehoverNode', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidDehoverNode(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -83,17 +83,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("dehover_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('dehover_node.jstree', data); }); - test("events#eventDidDeselectNode", async function(assert) { + test('events#eventDidDeselectNode', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidDeselectNode(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -103,17 +103,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("deselect_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('deselect_node.jstree', data); }); - test("events#eventDidHoverNode", async function(assert) { + test('events#eventDidHoverNode', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidHoverNode(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -123,17 +123,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("hover_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('hover_node.jstree', data); }); - test("events#eventDidInit", async function(assert) { + test('events#eventDidInit', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidInit() { assert.notOk(arguments.length); - } + }, }); await render(hbs` @@ -143,17 +143,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("init.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('init.jstree', data); }); - test("events#eventIsLoading", async function(assert) { + test('events#eventIsLoading', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventIsLoading() { assert.notOk(arguments.length); - } + }, }); await render(hbs` @@ -163,17 +163,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("loading.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('loading.jstree', data); }); - test("events#eventDidLoad", async function(assert) { + test('events#eventDidLoad', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidLoad() { assert.notOk(arguments.length); - } + }, }); await render(hbs` @@ -183,17 +183,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("loaded.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('loaded.jstree', data); }); - test("events#eventDidBecomeReady", async function(assert) { + test('events#eventDidBecomeReady', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidBecomeReady() { assert.notOk(arguments.length); - } + }, }); await render(hbs` @@ -203,17 +203,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("ready.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('ready.jstree', data); }); - test("events#eventDidRedraw", async function(assert) { + test('events#eventDidRedraw', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidRedraw() { assert.notOk(arguments.length); - } + }, }); await render(hbs` @@ -223,17 +223,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("redraw.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('redraw.jstree', data); }); - test("events#eventDidShowNode", async function(assert) { + test('events#eventDidShowNode', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidShowNode(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -243,17 +243,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("show_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('show_node.jstree', data); }); - test("events#eventDidSelectNode", async function(assert) { + test('events#eventDidSelectNode', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidSelectNode(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -263,17 +263,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("select_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('select_node.jstree', data); }); - test("events#eventDidDestroy", async function(assert) { + test('events#eventDidDestroy', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidDestroy() { assert.notOk(arguments.length); - } + }, }); await render(hbs` @@ -284,13 +284,13 @@ module("Integration | Component | ember-jstree", function(hooks) { `); }); - test("events#eventDidMoveNode", async function(assert) { + test('events#eventDidMoveNode', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidMoveNode(e) { assert.equal(e, data); - } + }, }); await render(hbs` @@ -300,17 +300,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("move_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('move_node.jstree', data); }); - test("events#eventDidDisableCheckbox", async function(assert) { + test('events#eventDidDisableCheckbox', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidDisableCheckbox(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -321,17 +321,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("disable_checkbox.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('disable_checkbox.jstree', data); }); - test("events#eventDidEnableCheckbox", async function(assert) { + test('events#eventDidEnableCheckbox', async function (assert) { const data = { node: {} }; this.setProperties({ data, eventDidEnableCheckbox(e) { assert.equal(e, data.node); - } + }, }); await render(hbs` @@ -342,11 +342,11 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("enable_checkbox.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('enable_checkbox.jstree', data); }); - test("events#eventDidCheckNode", async function(assert) { + test('events#eventDidCheckNode', async function (assert) { const data = { node: {}, selected: {}, event: {} }; this.setProperties({ data, @@ -354,7 +354,7 @@ module("Integration | Component | ember-jstree", function(hooks) { assert.equal(node, data.node); assert.equal(selected, data.selected); assert.equal(event, data.event); - } + }, }); await render(hbs` @@ -365,11 +365,11 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("check_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('check_node.jstree', data); }); - test("events#eventDidUncheckNode", async function(assert) { + test('events#eventDidUncheckNode', async function (assert) { const data = { node: {}, selected: {}, event: {} }; this.setProperties({ data, @@ -377,7 +377,7 @@ module("Integration | Component | ember-jstree", function(hooks) { assert.equal(node, data.node); assert.equal(selected, data.selected); assert.equal(event, data.event); - } + }, }); await render(hbs` @@ -388,17 +388,17 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("uncheck_node.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('uncheck_node.jstree', data); }); - test("events#eventDidCheckAll", async function(assert) { + test('events#eventDidCheckAll', async function (assert) { const data = { selected: {} }; this.setProperties({ data, eventDidCheckAll(e) { assert.equal(e, data.selected); - } + }, }); await render(hbs` @@ -409,18 +409,18 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("check_all.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('check_all.jstree', data); }); - test("events#eventDidUncheckAll", async function(assert) { + test('events#eventDidUncheckAll', async function (assert) { const data = { node: {}, selected: {} }; this.setProperties({ data, eventDidUncheckAll(node, selected) { assert.equal(node, data.node); assert.equal(selected, data.selected); - } + }, }); await render(hbs` @@ -431,7 +431,7 @@ module("Integration | Component | ember-jstree", function(hooks) { }} `); - const tree = $(find(".jstree")); - tree.trigger("uncheck_all.jstree", data); + const tree = jQuery(find('.jstree')); + tree.trigger('uncheck_all.jstree', data); }); }); diff --git a/tests/test-helper.js b/tests/test-helper.js index 4e29302..4efd6e5 100644 --- a/tests/test-helper.js +++ b/tests/test-helper.js @@ -1,8 +1,12 @@ -import Application from "../app"; -import config from "../config/environment"; -import { setApplication } from "@ember/test-helpers"; -import { start } from "ember-qunit"; +import Application from 'dummy/app'; +import config from 'dummy/config/environment'; +import * as QUnit from 'qunit'; +import { setApplication } from '@ember/test-helpers'; +import { setup } from 'qunit-dom'; +import { start } from 'ember-qunit'; setApplication(Application.create(config.APP)); +setup(QUnit.assert); + start(); From 37e129e42b96e87c5a3c0dab2f2afe9b94aeaeae Mon Sep 17 00:00:00 2001 From: Tyler Bratton Date: Thu, 6 Mar 2025 11:15:30 -0500 Subject: [PATCH 3/4] Remove Ember global, convert to glimmer component --- .eslintrc.js | 4 +- addon/components/ember-jstree.hbs | 8 + addon/components/ember-jstree.js | 1123 +++++++++++------ addon/mixins/ember-jstree-actions.js | 312 ----- app/components/ember-jstree.js | 2 +- config/ember-try.js | 16 +- config/environment.js | 2 +- ember-cli-build.js | 13 +- index.js | 8 +- package.json | 8 +- testem.js | 2 +- tests/acceptance/ember-jstree-test.js | 102 +- tests/dummy/app/controllers/application.js | 4 +- tests/dummy/app/dynamic/controller.js | 149 +-- tests/dummy/app/dynamic/template.hbs | 82 +- tests/dummy/app/static/controller.js | 273 ++-- tests/dummy/app/static/template.hbs | 129 +- tests/dummy/app/templates/application.hbs | 18 +- tests/dummy/config/environment.js | 22 +- tests/dummy/config/targets.js | 2 +- .../components/ember-jstree-test.js | 296 ++--- 21 files changed, 1318 insertions(+), 1257 deletions(-) create mode 100644 addon/components/ember-jstree.hbs delete mode 100644 addon/mixins/ember-jstree-actions.js diff --git a/.eslintrc.js b/.eslintrc.js index be97aa2..aebf010 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,7 +10,7 @@ module.exports = { legacyDecorators: true, }, }, - plugins: ["ember", "prettier"], + plugins: ['ember', 'prettier'], extends: [ 'eslint:recommended', 'plugin:ember/recommended', @@ -35,7 +35,7 @@ module.exports = { './tests/dummy/config/**/*.js', ], parserOptions: { - sourceType: "script", + sourceType: 'script', }, env: { browser: false, diff --git a/addon/components/ember-jstree.hbs b/addon/components/ember-jstree.hbs new file mode 100644 index 0000000..3efc78a --- /dev/null +++ b/addon/components/ember-jstree.hbs @@ -0,0 +1,8 @@ +
+ {{yield}} +
\ No newline at end of file diff --git a/addon/components/ember-jstree.js b/addon/components/ember-jstree.js index 3ceb634..5b8f554 100644 --- a/addon/components/ember-jstree.js +++ b/addon/components/ember-jstree.js @@ -1,101 +1,156 @@ -import Ember from 'ember'; -import Component from '@ember/component'; -import InboundActions from 'ember-component-inbound-actions/inbound-actions'; -import EmberJstreeActions from 'ember-cli-jstree/mixins/ember-jstree-actions'; -import { registerWaiter, unregisterWaiter } from '@ember/test'; -import { observer } from '@ember/object'; -import { isPresent, typeOf } from '@ember/utils'; -import { A } from '@ember/array'; +import { getOwner } from '@ember/application'; +import { A, isArray } from '@ember/array'; +import { action } from '@ember/object'; +import { isPresent, isNone, typeOf } from '@ember/utils'; +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; + +import { runTask, scheduleTask } from 'ember-lifeline'; import jQuery from 'jquery'; -import { next, schedule } from '@ember/runloop'; -const { testing } = Ember; +import { warn } from '@ember/debug'; +import { buildWaiter } from '@ember/test-waiters'; -export default Component.extend(InboundActions, EmberJstreeActions, { +const waiter = buildWaiter('ember-cli-jstree:ember-jstree-waiter'); + +export default class EmberJstree extends Component { // Properties for Ember communication - actionReceiver: null, - currentNode: null, - selectedNodes: null, + @tracked _selectedNodes = null; + get selectedNodes() { + return this._selectedNodes; + } + + set selectedNodes(selectedNodes) { + this._selectedNodes = selectedNodes; + this.args.onUpdateSelectedNodes?.(selectedNodes); + } // Basic configuration objects - data: A(), - plugins: A(), - themes: A(), - checkCallback: true, - multiple: true, - worker: true, + get data() { + return this.args.data || []; + } + + get plugins() { + return this.args.plugins || []; + } + + get themes() { + return this.args.themes || []; + } + + get checkCallback() { + return this.args.checkCallback ?? true; + } + + get multiple() { + return this.args.multiple ?? true; + } + + get worker() { + return this.args.worker ?? true; + } // Refresh configuration variables - skipLoading: false, - forgetState: false, + get skipLoading() { + return this.args.skipLoading; + } + + get forgetState() { + return this.args.forgetState; + } // Plugin option objects - checkboxOptions: null, - contextmenuOptions: null, - typesOptions: null, - searchOptions: null, - dndOptions: null, - sort: null, + get checkboxOptions() { + return this.args.checkboxOptions; + } - selectionDidChange: null, - treeObject: null, + get contextmenuOptions() { + return this.args.contextmenuOptions; + } - // Internals - _isDestroying: false, + get typesOptions() { + return this.args.typesOptions; + } + + get searchOptions() { + return this.args.searchOptions; + } - isReady: false, - _searchTerm: null, + get dndOptions() { + return this.args.dndOptions; + } - _isReadyTestWaiter() { - return this.isReady === true; - }, + get sort() { + return this.args.sort; + } - didInsertElement() { - this._super(...arguments); - schedule('afterRender', this, this.createTree); - }, + @tracked selectionDidChange = null; + @tracked treeObject = null; - createTree() { - if (testing) { + // Internals + @tracked _isDestroying = false; + @tracked _searchTerm = null; + @tracked _isReady = false; + + get isReady() { + return this._isReady; + } + + set isReady(value) { + this._isReady = value; + if (this.testWaiterToken) { + waiter.endAsync(this.testWaiterToken); + this.testWaiterToken = null; + } + } + + get isTesting() { + return ( + getOwner(this).resolveRegistration('config:environment').environment === + 'test' + ); + } + + @action + createTree(element) { + if (this.isTesting) { // Add test waiter. - registerWaiter(this, this._isReadyTestWaiter); + this.testWaiterToken = waiter.beginAsync(); } - let treeObject = this._setupJsTree(); + let treeObject = this._setupJsTree(element); this._setupEventHandlers(treeObject); - this.set('treeObject', treeObject); - }, - - willDestroyElement() { - this._super(...arguments); - if (testing) { - unregisterWaiter(this, this._isReadyTestWaiter); - } - - this.set('isReady', false); - this.set('_isDestroying', true); - this.send('destroy'); - }, + this.treeObject = treeObject; + this.args.onSetupActionReceiver?.(this); + } - didUpdateAttrs() { - this._super(...arguments); + @action + teardownJsTree() { + this.isReady = false; + this._isDestroying = true; + this.handleDestroy(); + } + @action + updateSearch() { let pluginsArray = this.plugins; - if (isPresent(pluginsArray)) { - let searchOptions = this.searchOptions; - if (isPresent(searchOptions) && pluginsArray.indexOf('search') >= 0) { - let searchTerm = this.searchTerm; - if (this._searchTerm !== searchTerm) { - next('afterRender', () => { - this.set('_searchTerm', searchTerm); - this.getTree().search(searchTerm); - }); - } + let searchOptions = this.searchOptions; + if (!isPresent(pluginsArray) || !isPresent(searchOptions)) { + return; + } + + if (pluginsArray.includes('search')) { + const searchTerm = this.args.searchTerm; + if (this._searchTerm !== searchTerm) { + scheduleTask(this, 'actions', () => { + this._searchTerm = searchTerm; + this.getTree().search(searchTerm); + }); } } - }, + } /** * Main setup function that registers all the plugins and sets up the core @@ -103,9 +158,11 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * * @method _setupJsTree */ - _setupJsTree() { - return jQuery(this.element).jstree(this._buildConfig()); - }, + _setupJsTree(element) { + /* eslint-disable ember/no-jquery */ + return jQuery(element).jstree(this._buildConfig()); + /* eslint-enable ember/no-jquery */ + } /** * Builds config object for jsTree. Could be used to override config in descendant classes. @@ -113,9 +170,9 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * @method _buildConfig */ _buildConfig() { - let configObject = {}; + const configObject = {}; - configObject['core'] = { + configObject.core = { data: this.data, check_callback: this.checkCallback, multiple: this.multiple, @@ -124,13 +181,13 @@ export default Component.extend(InboundActions, EmberJstreeActions, { let themes = this.themes; if (isPresent(themes) && typeOf(themes) === 'object') { - configObject['core']['themes'] = themes; + configObject.core.themes = themes; } let pluginsArray = this.plugins; if (isPresent(pluginsArray)) { pluginsArray = pluginsArray.replace(/ /g, '').split(','); - configObject['plugins'] = pluginsArray; + configObject.plugins = pluginsArray; if ( pluginsArray.includes('contextmenu') || @@ -138,33 +195,33 @@ export default Component.extend(InboundActions, EmberJstreeActions, { pluginsArray.includes('unique') ) { // These plugins need core.check_callback - configObject['core']['check_callback'] = - configObject['core']['check_callback'] || true; + configObject.core.check_callback = + configObject.core.check_callback || true; } let checkboxOptions = this.checkboxOptions; if (isPresent(checkboxOptions) && pluginsArray.includes('checkbox')) { - configObject['checkbox'] = checkboxOptions; + configObject.checkbox = checkboxOptions; } let searchOptions = this.searchOptions; if (isPresent(searchOptions) && pluginsArray.includes('search')) { - configObject['search'] = searchOptions; + configObject.search = searchOptions; } let sort = this.sort; if (isPresent(sort) && pluginsArray.includes('sort')) { - configObject['sort'] = sort; + configObject.sort = sort; } let stateOptions = this.stateOptions; if (isPresent(stateOptions) && pluginsArray.includes('state')) { - configObject['state'] = stateOptions; + configObject.state = stateOptions; } let typesOptions = this.typesOptions; if (isPresent(typesOptions) && pluginsArray.includes('types')) { - configObject['types'] = typesOptions; + configObject.types = typesOptions; } let contextmenuOptions = this.contextmenuOptions; @@ -172,18 +229,17 @@ export default Component.extend(InboundActions, EmberJstreeActions, { isPresent(contextmenuOptions) && pluginsArray.includes('contextmenu') ) { - configObject['contextmenu'] = - this._setupContextMenus(contextmenuOptions); + configObject.contextmenu = this._setupContextMenus(contextmenuOptions); } let dndOptions = this.dndOptions; if (isPresent(dndOptions) && pluginsArray.includes('dnd')) { - configObject['dnd'] = dndOptions; + configObject.dnd = dndOptions; } } return configObject; - }, + } /** * Setup context menu action handlers to handle ember actions @@ -193,29 +249,29 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * @return {Array} An Array of Ember-friendly options to pass back into the config object */ _setupContextMenus(contextmenuOptions) { - if (typeOf(contextmenuOptions['items']) === 'object') { + if (typeOf(contextmenuOptions.items) === 'object') { let newMenuItems = {}; let menuItems = Object.keys(contextmenuOptions['items']); for (let menuItem of menuItems) { - let itemData = contextmenuOptions['items'][menuItem]; + let itemData = contextmenuOptions.items[menuItem]; newMenuItems[menuItem] = itemData; // Only change if not a function // This needs to be done to handle Ember actions - if (typeOf(itemData['action']) !== 'function') { - let emberAction = itemData['action']; + if (typeOf(itemData.action) !== 'function') { + let emberAction = itemData.action; - newMenuItems[menuItem]['action'] = (data) => { - this.send('contextmenuItemDidClick', emberAction, data); + newMenuItems[menuItem].action = (data) => { + this.contextmenuItemDidClick(emberAction, data); }; } } - contextmenuOptions['items'] = newMenuItems; + contextmenuOptions.items = newMenuItems; } return contextmenuOptions; - }, + } /** * Register all sorts of events @@ -233,350 +289,290 @@ export default Component.extend(InboundActions, EmberJstreeActions, { } /* - Event: init.jstree - Action: eventDidInit - triggered after all events are bound - */ - treeObject.on('init.jstree', () => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidInit'); - }); - }); + Event: init.jstree + Action: eventDidInit + triggered after all events are bound + */ + treeObject.on('init.jstree', () => + runTask(this, () => this.callAction('eventDidInit'), 1) + ); /* - Event: loading.jstree - Action: eventIsLoading - triggered after the loading text is shown and before loading starts - */ - treeObject.on('loading.jstree', () => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventIsLoading'); - }); - }); + Event: loading.jstree + Action: eventIsLoading + triggered after the loading text is shown and before loading starts + */ + treeObject.on('loading.jstree', () => + runTask(this, () => this.callAction('eventIsLoading'), 1) + ); /* - Event: loaded.jstree - Action: eventDidLoad - triggered after the root node is loaded for the first time - */ - treeObject.on('loaded.jstree', () => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidLoad'); - }); - }); + Event: loaded.jstree + Action: eventDidLoad + triggered after the root node is loaded for the first time + */ + treeObject.on('loaded.jstree', () => + runTask(this, () => this.callAction('eventDidLoad'), 1) + ); /* - Event: ready.jstree - Action: eventDidBecomeReady - triggered after all nodes are finished loading - */ + Event: ready.jstree + Action: eventDidBecomeReady + triggered after all nodes are finished loading + */ treeObject.on('ready.jstree', () => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.set('isReady', true); - this.callAction('eventDidBecomeReady'); - }); + runTask( + this, + () => { + this.isReady = true; + this.callAction('eventDidBecomeReady'); + }, + 1 + ); }); /* - Event: redraw.jstree - Action: eventDidRedraw - triggered after nodes are redrawn - */ - treeObject.on('redraw.jstree', () => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidRedraw'); - }); - }); + Event: redraw.jstree + Action: eventDidRedraw + triggered after nodes are redrawn + */ + treeObject.on('redraw.jstree', () => + runTask(this, () => this.callAction('eventDidRedraw'), 1) + ); /* - Event: after_open.jstree - Action: eventDidOpen - triggered when a node is opened and the animation is complete - */ - treeObject.on('after_open.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidOpen', data.node); - }); - }); + Event: after_open.jstree + Action: eventDidOpen + triggered when a node is opened and the animation is complete + */ + treeObject.on('after_open.jstree', (event, data) => + runTask(this, () => this.callAction('eventDidOpen', data.node), 1) + ); /* - Event: after_close.jstree - Action: eventDidClose - triggered when a node is closed and the animation is complete - */ - treeObject.on('after_close.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidClose', data.node); - }); - }); + Event: after_close.jstree + Action: eventDidClose + triggered when a node is closed and the animation is complete + */ + treeObject.on('after_close.jstree', (event, data) => + runTask(this, () => this.callAction('eventDidClose', data.node), 1) + ); /* - Event: select_node.jstree - Action: eventDidSelectNode - triggered when an node is selected - */ + Event: select_node.jstree + Action: eventDidSelectNode + triggered when a node is selected + */ treeObject.on('select_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction( - 'eventDidSelectNode', - data.node, - data.selected, - data.event - ); - }); + runTask( + this, + () => + this.callAction( + 'eventDidSelectNode', + data.node, + data.selected, + data.event + ), + 1 + ); }); /* - Event: deselect_node.jstree - Action: eventDidDeselectNode - triggered when an node is deselected - */ + Event: deselect_node.jstree + Action: eventDidDeselectNode + triggered when an node is deselected + */ treeObject.on('deselect_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction( - 'eventDidDeselectNode', - data.node, - data.selected, - data.event - ); - }); + runTask( + this, + () => + this.callAction( + 'eventDidDeselectNode', + data.node, + data.selected, + data.event + ), + 1 + ); }); /* - Event: changed.jstree - Action: jstreeDidChange - triggered when selection changes - */ + Event: changed.jstree + Action: jstreeDidChange + triggered when selection changes + */ treeObject.on('changed.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - - // Check if selection changed - if (isPresent(this.treeObject)) { - let selectionChangedEventNames = [ - 'model', - 'select_node', - 'deselect_node', - 'select_all', - 'deselect_all', - ]; - if ( - isPresent(data.action) && - selectionChangedEventNames.includes(data.action) - ) { - let selNodes = A(this.treeObject.jstree(true).get_selected(true)); - this.set('selectedNodes', selNodes); + runTask( + this, + () => { + // Check if selection changed + if (isPresent(this.treeObject)) { + const selectionChangedEventNames = [ + 'model', + 'select_node', + 'deselect_node', + 'select_all', + 'deselect_all', + ]; + if ( + isPresent(data.action) && + selectionChangedEventNames.includes(data.action) + ) { + this.selectedNodes = A( + this.treeObject.jstree(true).get_selected(true) + ); + } } - } - this.callAction('eventDidChange', data); - }); + this.callAction('eventDidChange', data); + }, + 1 + ); }); /* - Event: hover_node.jstree - Action: eventDidHoverNode - triggered when a node is hovered - */ - treeObject.on('hover_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidHoverNode', data.node); - }); - }); + Event: hover_node.jstree + Action: eventDidHoverNode + triggered when a node is hovered + */ + treeObject.on('hover_node.jstree', (event, data) => + runTask(this, () => this.callAction('eventDidHoverNode', data.node), 1) + ); /* - Event: dehover_node.jstree - Action: eventDidDehoverNode - triggered when a node is no longer hovered - */ - treeObject.on('dehover_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidDehoverNode', data.node); - }); - }); + Event: dehover_node.jstree + Action: eventDidDehoverNode + triggered when a node is no longer hovered + */ + treeObject.on('dehover_node.jstree', (event, data) => + runTask(this, () => this.callAction('eventDidDehoverNode', data.node), 1) + ); /* - Event: show_node.jstree - Action: eventDidShowNode - triggered when a node is no longer hovered - */ - treeObject.on('show_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidShowNode', data.node); - }); - }); + Event: show_node.jstree + Action: eventDidShowNode + triggered when a node is no longer hovered + */ + treeObject.on('show_node.jstree', (event, data) => + runTask(this, () => this.callAction('eventDidShowNode', data.node), 1) + ); /* - Event: move_node.jstree - Action: eventDidMoveNode - triggered when a node is moved - */ - treeObject.on('move_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidMoveNode', data); - }); - }); - - let pluginsArray = this.plugins; - - if (isPresent(pluginsArray) && pluginsArray.indexOf('search') > -1) { + Event: move_node.jstree + Action: eventDidMoveNode + triggered when a node is moved + */ + treeObject.on('move_node.jstree', (event, data) => + runTask(this, () => this.callAction('eventDidMoveNode', data), 1) + ); + + const pluginsArray = this.plugins; + if (isPresent(pluginsArray) && pluginsArray.includes('search')) { /* - Event: search.jstree - Action: eventDidSearch - triggered when a search action is performed + Event: search.jstree + Action: eventDidSearch + triggered when a search action is performed */ - treeObject.on('search.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidSearch', event, data); - }); - }); + treeObject.on('search.jstree', (event, data) => + runTask(this, () => this.callAction('eventDidSearch', event, data), 1) + ); } - if (isPresent(pluginsArray) && pluginsArray.indexOf('checkbox') > -1) { + if (isPresent(pluginsArray) && pluginsArray.includes('checkbox')) { /* - Event: disable_checkbox.jstree - Action: eventDidDisableCheckbox - triggered when an node's checkbox is disabled - */ - treeObject.on('disable_checkbox.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidDisableCheckbox', data.node); - }); - }); + Event: disable_checkbox.jstree + Action: eventDidDisableCheckbox + triggered when an node's checkbox is disabled + */ + treeObject.on('disable_checkbox.jstree', (event, data) => + runTask( + this, + () => this.callAction('eventDidDisableCheckbox', data.node), + 1 + ) + ); /* - Event: enable_checkbox.jstree - Action: eventDidEnableCheckbox - triggered when an node's checkbox is enabled - */ - treeObject.on('enable_checkbox.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidEnableCheckbox', data.node); - }); - }); + Event: enable_checkbox.jstree + Action: eventDidEnableCheckbox + triggered when an node's checkbox is enabled + */ + treeObject.on('enable_checkbox.jstree', (event, data) => + runTask( + this, + () => this.callAction('eventDidEnableCheckbox', data.node), + 1 + ) + ); - if ( - isPresent('checkboxOptions.tie_selected') && - !this.get('checkboxOptions.tie_selected') - ) { + if (this.checkboxOptions && !this.checkboxOptions.tie_selected) { /* - Event: check_node.jstree - Action: eventDidCheckNode - triggered when an node is checked (only if tie_selection in checkbox settings is false) - */ - treeObject.on('check_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction( - 'eventDidCheckNode', - data.node, - data.selected, - data.event - ); - }); - }); + Event: check_node.jstree + Action: eventDidCheckNode + triggered when an node is checked (only if tie_selection in checkbox settings is false) + */ + treeObject.on('check_node.jstree', (event, data) => + runTask( + this, + () => + this.callAction( + 'eventDidCheckNode', + data.node, + data.selected, + data.event + ), + 1 + ) + ); /* - Event: uncheck_node.jstree - Action: eventDidUncheckNode - triggered when an node is unchecked (only if tie_selection in checkbox settings is false) - */ - treeObject.on('uncheck_node.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction( - 'eventDidUncheckNode', - data.node, - data.selected, - data.event - ); - }); - }); + Event: uncheck_node.jstree + Action: eventDidUncheckNode + triggered when an node is unchecked (only if tie_selection in checkbox settings is false) + */ + treeObject.on('uncheck_node.jstree', (event, data) => + runTask( + this, + () => + this.callAction( + 'eventDidUncheckNode', + data.node, + data.selected, + data.event + ), + 1 + ) + ); /* - Event: check_all.jstree - Action: eventDidCheckAll - triggered when all nodes are checked (only if tie_selection in checkbox settings is false) - */ - treeObject.on('check_all.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidCheckAll', data.selected); - }); - }); + Event: check_all.jstree + Action: eventDidCheckAll + triggered when all nodes are checked (only if tie_selection in checkbox settings is false) + */ + treeObject.on('check_all.jstree', (event, data) => + runTask( + this, + () => this.callAction('eventDidCheckAll', data.selected), + 1 + ) + ); /* - Event: uncheck_all.jstree - Action: eventDidUncheckAll - triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) - */ - treeObject.on('uncheck_all.jstree', (event, data) => { - next(this, function () { - if (this.isDestroyed || this.isDestroying) { - return; - } - this.callAction('eventDidUncheckAll', data.node, data.selected); - }); - }); + Event: uncheck_all.jstree + Action: eventDidUncheckAll + triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) + */ + treeObject.on('uncheck_all.jstree', (event, data) => + runTask( + this, + () => + this.callAction('eventDidUncheckAll', data.node, data.selected), + 1 + ) + ); } } - }, + } /** * Refreshes the data in the tree @@ -584,32 +580,355 @@ export default Component.extend(InboundActions, EmberJstreeActions, { * * @method _redrawTree */ - _refreshTree: observer('data', function () { + @action + _refreshTree() { let tree = this.getTree(); if (null !== tree && false !== tree) { - tree.settings.core['data'] = this.data; + tree.settings.core.data = this.data; tree.refresh(this.skipLoading, this.forgetState); } else { // setup again if destroyed let treeObject = this._setupJsTree(); this._setupEventHandlers(treeObject); - this.set('treeObject', treeObject); + this.treeObject = treeObject; } - }), + } getTree() { let tree = this.treeObject; return tree.jstree(true); - }, + } + + callAction(actionName, ...args) { + if (actionName === 'destroy') { + actionName = 'handleDestroy'; + } + + let action = this[actionName] || this.args[actionName]; + if (typeOf(action) === 'function') { + return action(...args); + } + } + + _jsTreeFindNodeMatches(property, values) { + let treeObject = this.treeObject; + let nodes = []; + + if ('id' === property) { + // If property is ID, can use get_node, which is faster than search. + if (isArray(values)) { + for (let i = 0; i < values.length; i++) { + let node = treeObject.jstree(true).get_node(values[i]); + nodes.push(node); + } + } + } else { + if (!isArray(values)) { + values = A([values]); + } + + let data = treeObject.jstree(true)._model.data; + let dataKeys = Object.keys(data); + + for (let i = 0; i < values.length; i++) { + let value = values[i]; + if (!isNone(value)) { + for (let j = 0; j < dataKeys.length; j++) { + let node = data[dataKeys[j]]; + if ( + typeOf(node.original) !== 'undefined' && + node.original[property] === value + ) { + nodes.push(node); + break; + } + } + } + } + } + + return nodes; + } + + @action + contextmenuItemDidClick(actionName, data) { + let emberTreeObj = this.getTree; + + let instance = jQuery.jstree.reference(data.reference); + let node = instance.get_node(data.reference); + + this.callAction(actionName, node, emberTreeObj); + } + + @action + redraw() { + // Redraw true currently does not work as intended. Need to investigate. + this._refreshTree(); + } - actions: { - contextmenuItemDidClick(actionName, data) { - let emberTreeObj = this.getTree; + @action + handleDestroy() { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + if (!this.isTesting && !this._isDestroying) { + treeObject.jstree(true).destroy(); + } + + this.callAction('eventDidDestroy'); + } + } + + @action + getNode(nodeId) { + if (typeOf(nodeId) !== 'string') { + throw new Error( + 'getNode() requires a node ID to be passed to it to return the node!' + ); + } + + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionGetNode', + treeObject.jstree(true).get_node(nodeId) + ); + } + } - let instance = jQuery.jstree.reference(data.reference); - let node = instance.get_node(data.reference); + @action + getText(obj) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction('actionGetText', treeObject.jstree(true).get_text(obj)); + } + } + + @action + getPath(obj, glue, ids) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionGetPath', + treeObject.jstree(true).get_path(obj, glue, ids) + ); + } + } + + @action + getChildrenDom(obj) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionGetChildrenDom', + treeObject.jstree(true).get_children_dom(obj) + ); + } + } + + @action + getContainer() { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionGetContainer', + treeObject.jstree(true).get_container() + ); + } + } + + @action + getParent(obj) { + obj = obj || '#'; + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionGetParent', + treeObject.jstree(true).get_parent(obj) + ); + } + } + + @action + loadNode(obj, cb) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionLoadNode', + treeObject.jstree(true).load_node(obj, cb) + ); + } + } + + @action + loadAll(obj, cb) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionLoadAll', + treeObject.jstree(true).load_all(obj, cb) + ); + } + } + + @action + openNode(obj, cb, animation) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).open_node(obj, cb, animation); + } + } + + @action + openAll(obj, animation) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).open_all(obj, animation); + } + } + + @action + closeNode(obj, cb) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).close_node(obj, cb); + } + } + + @action + closeAll(obj, animation) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).close_all(obj, animation); + } + } + + @action + toggleNode(obj) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).toggle_node(obj); + } + } + + @action + createNode(obj, node, pos, callback, is_loaded) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionCreateNode', + treeObject.jstree(true).create_node(obj, node, pos, callback, is_loaded) + ); + } + } + + @action + renameNode(obj, val) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionRenameNode', + treeObject.jstree(true).rename_node(obj, val) + ); + } + } + + @action + moveNode(obj, par, pos, callback, is_loaded) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).move_node(obj, par, pos, callback, is_loaded); + } + } + + @action + copyNode(obj, par, pos, callback, is_loaded) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).copy_node(obj, par, pos, callback, is_loaded); + } + } + + @action + deleteNode(obj) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + this.callAction( + 'actionDeleteNode', + treeObject.jstree(true).delete_node(obj) + ); + } + } + + @action + selectNode(obj, suppress_event) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).select_node(obj, suppress_event); + } + } + + @action + deselectNode(obj, suppress_event) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).deselect_node(obj, suppress_event); + } + } + + @action + selectAll(suppress_event) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).select_all(suppress_event); + } + } + + @action + deselectAll(suppress_event) { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + treeObject.jstree(true).deselect_all(suppress_event); + } + } + + @action + lastError() { + let treeObject = this.treeObject; + if (!isNone(treeObject)) { + let e = treeObject.jstree(true).last_error(); + this._lastError = e; + this.callAction('actionLastError', e); + } + } + + @action + deselectNodes(property, values) { + if (arguments.length === 0) { + warn( + 'Using deselectNodes without parameters to deselect all nodes is deprecated. Use the deselectAll action to deselect all nodes.' + ); + this.deselectAll(); + return; + } + + let treeObject = this.treeObject; + let nodes = this._jsTreeFindNodeMatches(property, values); + + treeObject.jstree(true).deselect_node(nodes, true, true); + treeObject.jstree(true).redraw(); // Redraw so that parent nodes get their indicator changed. + } + + @action + selectNodes(property, values) { + let treeObject = this.treeObject; + if (null !== treeObject && !this.isDestroyed && !this.isDestroying) { + let nodes = this._jsTreeFindNodeMatches(property, values); + treeObject.jstree(true).select_node(nodes, true, true); + } + } - this.callAction(actionName, node, emberTreeObj); - }, - }, -}); + @action + send(actionName, ...args) { + this.callAction(actionName, ...args); + } +} diff --git a/addon/mixins/ember-jstree-actions.js b/addon/mixins/ember-jstree-actions.js deleted file mode 100644 index dd33607..0000000 --- a/addon/mixins/ember-jstree-actions.js +++ /dev/null @@ -1,312 +0,0 @@ -import Ember from "ember"; -import Mixin from "@ember/object/mixin"; -import { A, isArray } from "@ember/array"; -import { isNone, typeOf } from "@ember/utils"; -import { warn } from "@ember/debug"; - -const { testing } = Ember; - -/** - * Actions that are mapped to jstree and return Ember actions with parameters where necessary. - * These actions are passed to the addon via the actionReceiver property and are generally - * the same as jsTree method names, but camelized. - * - * @class EmberJstreeActions - */ -export default Mixin.create({ - callAction(actionName, ...args) { - let action = this.get(actionName); - - if (typeOf(action) === "function") { - return action(...args); - } - }, - - _jsTreeFindNodeMatches(property, values) { - let treeObject = this.get("treeObject"); - let nodes = []; - - if ("id" === property) { - // If property is ID, can use get_node, which is faster than search. - if (isArray(values)) { - for (let i = 0; i < values.length; i++) { - let node = treeObject.jstree(true).get_node(values[i]); - nodes.push(node); - } - } - } else { - if (!isArray(values)) { - values = A([values]); - } - - let data = treeObject.jstree(true)._model.data; - let dataKeys = Object.keys(data); - - for (let i = 0; i < values.length; i++) { - let value = values[i]; - if (!isNone(value)) { - for (let j = 0; j < dataKeys.length; j++) { - let node = data[dataKeys[j]]; - if ( - typeOf(node.original) !== "undefined" && - node.original[property] === value - ) { - nodes.push(node); - break; - } - } - } - } - } - - return nodes; - }, - - actions: { - redraw() { - // Redraw true currently does not work as intended. Need to investigate. - this._refreshTree(); - }, - - destroy() { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - if (!testing && !this.get("_isDestroying")) { - treeObject.jstree(true).destroy(); - } - - this.callAction("eventDidDestroy"); - } - }, - - getNode(nodeId) { - if (typeOf(nodeId) !== "string") { - throw new Error( - "getNode() requires a node ID to be passed to it to return the node!" - ); - } - - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionGetNode", - treeObject.jstree(true).get_node(nodeId) - ); - } - }, - - getText(obj) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction("actionGetText", treeObject.jstree(true).get_text(obj)); - } - }, - - getPath(obj, glue, ids) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionGetPath", - treeObject.jstree(true).get_path(obj, glue, ids) - ); - } - }, - - getChildrenDom(obj) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionGetChildrenDom", - treeObject.jstree(true).get_children_dom(obj) - ); - } - }, - - getContainer() { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionGetContainer", - treeObject.jstree(true).get_container() - ); - } - }, - - getParent(obj) { - obj = obj || "#"; - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionGetParent", - treeObject.jstree(true).get_parent(obj) - ); - } - }, - - loadNode(obj, cb) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionLoadNode", - treeObject.jstree(true).load_node(obj, cb) - ); - } - }, - - loadAll(obj, cb) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionLoadAll", - treeObject.jstree(true).load_all(obj, cb) - ); - } - }, - - openNode(obj, cb, animation) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).open_node(obj, cb, animation); - } - }, - - openAll(obj, animation) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).open_all(obj, animation); - } - }, - - closeNode(obj, cb) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).close_node(obj, cb); - } - }, - - closeAll(obj, animation) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).close_all(obj, animation); - } - }, - - toggleNode(obj) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).toggle_node(obj); - } - }, - - createNode(obj, node, pos, callback, is_loaded) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionCreateNode", - treeObject - .jstree(true) - .create_node(obj, node, pos, callback, is_loaded) - ); - } - }, - - renameNode(obj, val) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionRenameNode", - treeObject.jstree(true).rename_node(obj, val) - ); - } - }, - - moveNode(obj, par, pos, callback, is_loaded) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).move_node(obj, par, pos, callback, is_loaded); - } - }, - - copyNode(obj, par, pos, callback, is_loaded) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).copy_node(obj, par, pos, callback, is_loaded); - } - }, - - deleteNode(obj) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - this.callAction( - "actionDeleteNode", - treeObject.jstree(true).delete_node(obj) - ); - } - }, - - selectNode(obj, suppress_event) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).select_node(obj, suppress_event); - } - }, - - deselectNode(obj, suppress_event) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).deselect_node(obj, suppress_event); - } - }, - - selectAll(suppress_event) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).select_all(suppress_event); - } - }, - - deselectAll(suppress_event) { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - treeObject.jstree(true).deselect_all(suppress_event); - } - }, - - lastError() { - let treeObject = this.get("treeObject"); - if (!isNone(treeObject)) { - let e = treeObject.jstree(true).last_error(); - this.set("_lastError", e); - this.callAction("actionLastError", e); - } - }, - - deselectNodes(property, values) { - if (arguments.length === 0) { - warn( - "Using deselectNodes without parameters to deselect all nodes is deprecated. Use the deselectAll action to deselect all nodes." - ); - this.send("deselectAll"); - return; - } - - let treeObject = this.get("treeObject"); - let nodes = this._jsTreeFindNodeMatches(property, values); - - treeObject.jstree(true).deselect_node(nodes, true, true); - treeObject.jstree(true).redraw(); // Redraw so that parent nodes get their indicator changed. - }, - - selectNodes(property, values) { - let treeObject = this.get("treeObject"); - if ( - null !== treeObject && - !this.get("isDestroyed") && - !this.get("isDestroying") - ) { - let nodes = this._jsTreeFindNodeMatches(property, values); - treeObject.jstree(true).select_node(nodes, true, true); - } - } - } -}); diff --git a/app/components/ember-jstree.js b/app/components/ember-jstree.js index ec1482a..e57b85e 100644 --- a/app/components/ember-jstree.js +++ b/app/components/ember-jstree.js @@ -1 +1 @@ -export { default } from "ember-cli-jstree/components/ember-jstree"; +export { default } from 'ember-cli-jstree/components/ember-jstree'; diff --git a/config/ember-try.js b/config/ember-try.js index ad0d729..8e178a6 100644 --- a/config/ember-try.js +++ b/config/ember-try.js @@ -1,6 +1,6 @@ -"use strict"; +'use strict'; -const getChannelURL = require("ember-source-channel-url"); +const getChannelURL = require('ember-source-channel-url'); const { embroiderSafe, embroiderOptimized } = require('@embroider/test-setup'); module.exports = async function () { @@ -24,26 +24,26 @@ module.exports = async function () { }, }, { - name: "ember-release", + name: 'ember-release', npm: { devDependencies: { - "ember-source": await getChannelURL('release'), + 'ember-source': await getChannelURL('release'), }, }, }, { - name: "ember-beta", + name: 'ember-beta', npm: { devDependencies: { - "ember-source": await getChannelURL('beta'), + 'ember-source': await getChannelURL('beta'), }, }, }, { - name: "ember-canary", + name: 'ember-canary', npm: { devDependencies: { - "ember-source": await getChannelURL('canary'), + 'ember-source': await getChannelURL('canary'), }, }, }, diff --git a/config/environment.js b/config/environment.js index b723858..331ab30 100644 --- a/config/environment.js +++ b/config/environment.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; module.exports = function (/* environment, appConfig */) { return {}; diff --git a/ember-cli-build.js b/ember-cli-build.js index 4689674..cfeba0a 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -1,16 +1,9 @@ -"use strict"; +'use strict'; -const EmberAddon = require("ember-cli/lib/broccoli/ember-addon"); +const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); module.exports = function (defaults) { - let app = new EmberAddon(defaults, { - "ember-bootstrap": { - importBootstrapTheme: true, - bootstrapVersion: 3, - importBootstrapFont: true, - importBootstrapCSS: true - } - }); + let app = new EmberAddon(defaults, {}); /* This build file specifies the options for the dummy test app of this diff --git a/index.js b/index.js index 91fd4e6..9633cbe 100644 --- a/index.js +++ b/index.js @@ -28,7 +28,13 @@ module.exports = { treeForVendor(tree) { let registerVersionTree = writeFile( 'ember-cli-jstree/register-version.js', - `Ember.libraries.register('Ember CLI jsTree', '${version}')` + `let emberLibraries; + try { + emberLibraries = requireModule('ember')['default'].libraries; + } catch { + emberLibraries = window.Ember.libraries; + } + emberLibraries?.register('Ember CLI jsTree', '${version}');` ); let stylesTree = new Funnel( diff --git a/package.json b/package.json index 23c9f7b..c45188d 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "license": "MIT", "devDependencies": { "@ember/optional-features": "^2.0.0", + "@ember/render-modifiers": "^3.0.0", "@ember/test-helpers": "^2.6.0", "@embroider/test-setup": "^0.48.1", "@glimmer/component": "^1.0.4", @@ -37,7 +38,6 @@ "babel-eslint": "^10.1.0", "bootstrap": "^3.4.1", "broccoli-asset-rev": "^3.0.0", - "ember-auto-import": "^1.12.0", "ember-cli": "~3.28.6", "ember-cli-dependency-checker": "^3.2.0", "ember-cli-github-pages": "^0.2.0", @@ -47,7 +47,7 @@ "ember-disable-prototype-extensions": "^1.1.3", "ember-export-application-global": "^2.0.1", "ember-load-initializers": "^2.1.2", - "ember-maybe-import-regenerator": "^0.1.6", + "ember-modifier": "^4.2.0", "ember-page-title": "^6.2.2", "ember-qunit": "^5.1.5", "ember-resolver": "^8.0.3", @@ -75,12 +75,14 @@ ], "dependencies": { "@ember/jquery": "^2.0.0", + "@ember/test-waiters": "^4.0.0", "broccoli-file-creator": "^2.1.1", "broccoli-funnel": "^3.0.8", "broccoli-merge-trees": "^4.2.0", + "ember-auto-import": "^2.10.0", "ember-cli-babel": "^7.26.10", "ember-cli-htmlbars": "^5.7.2", - "ember-component-inbound-actions": "^1.2.1", + "ember-lifeline": "^7.0.0", "jstree": "^3.3.5" }, "ember": { diff --git a/testem.js b/testem.js index b1d3806..ed2f371 100644 --- a/testem.js +++ b/testem.js @@ -1,7 +1,7 @@ 'use strict'; module.exports = { - test_page: "tests/index.html?hidepassed", + test_page: 'tests/index.html?hidepassed', disable_watching: true, launch_in_ci: ['Chrome'], launch_in_dev: ['Chrome'], diff --git a/tests/acceptance/ember-jstree-test.js b/tests/acceptance/ember-jstree-test.js index 6bfd94c..9fa55ac 100644 --- a/tests/acceptance/ember-jstree-test.js +++ b/tests/acceptance/ember-jstree-test.js @@ -1,122 +1,122 @@ -import { click, fillIn, findAll, find, visit } from "@ember/test-helpers"; -import { setupApplicationTest } from "ember-qunit"; -import { module, test } from "qunit"; +import { click, fillIn, findAll, find, visit } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import { module, test } from 'qunit'; -module("Acceptance - ember-cli-jstree", function(hooks) { +module('Acceptance - ember-cli-jstree', function (hooks) { setupApplicationTest(hooks); - test("Has static demo", async function(assert) { + test('Has static demo', async function (assert) { assert.expect(1); - await visit("/static"); + await visit('/static'); assert.equal( - findAll(".sample-tree").length, + findAll('.sample-tree').length, 1, - "Static page contains a sample tree" + 'Static page contains a sample tree' ); }); - test("Destroy button destroys jstreeObject", async function(assert) { + test('Destroy button destroys jstreeObject', async function (assert) { assert.expect(1); - await visit("/static"); - await click(".ember-test-destroy-button"); + await visit('/static'); + await click('.ember-test-destroy-button'); assert.equal( - findAll(".sample-tree:first-child").length, + findAll('.sample-tree:first-child').length, 0, - "Tree should be destroyed" + 'Tree should be destroyed' ); }); - test("Get Node button gets correct node", async function(assert) { + test('Get Node button gets correct node', async function (assert) { assert.expect(2); - await visit("/static"); - await click(".ember-test-getnode-button"); + await visit('/static'); + await click('.ember-test-getnode-button'); const object = { - id: "rn2", - text: "Opened node (has tooltip)", + id: 'rn2', + text: 'Opened node (has tooltip)', icon: true, - parent: "#", - parents: ["#"], - children: ["j1_5", "j1_6"], - children_d: ["j1_5", "j1_6"], + parent: '#', + parents: ['#'], + children: ['j1_5', 'j1_6'], + children_d: ['j1_5', 'j1_6'], data: null, state: { loaded: true, opened: true, selected: true, disabled: false }, - li_attr: { id: "rn2" }, + li_attr: { id: 'rn2' }, a_attr: { - href: "#", - class: "hint--bottom", - "data-hint": "This is a bottom mounted node tooltip", - id: "rn2_anchor" + href: '#', + class: 'hint--bottom', + 'data-hint': 'This is a bottom mounted node tooltip', + id: 'rn2_anchor', }, original: { - id: "rn2", - text: "Opened node (has tooltip)", + id: 'rn2', + text: 'Opened node (has tooltip)', state: { opened: true, selected: true }, - class: "hint--bottom", + class: 'hint--bottom', a_attr: { - class: "hint--bottom", - "data-hint": "This is a bottom mounted node tooltip" - } - } + class: 'hint--bottom', + 'data-hint': 'This is a bottom mounted node tooltip', + }, + }, }; - const compare = JSON.parse(find(".ember-test-buffer").textContent); + const compare = JSON.parse(find('.ember-test-buffer').textContent); assert.equal( compare.text, object.text, - "getNode should return the correct node title" + 'getNode should return the correct node title' ); assert.equal( compare.parent, object.parent, - "getNode should return the correct node parent ID (#)" + 'getNode should return the correct node parent ID (#)' ); }); - test("Search filters to correct nodes", async function(assert) { + test('Search filters to correct nodes', async function (assert) { assert.expect(3); - await visit("/static"); + await visit('/static'); assert.equal( - findAll(".sample-tree li.jstree-hidden").length, + findAll('.sample-tree li.jstree-hidden').length, 0, - "All nodes begin visible" + 'All nodes begin visible' ); - await fillIn(".search-input", "Single child node"); + await fillIn('.search-input', 'Single child node'); assert.equal( - findAll(".sample-tree li:not(.jstree-hidden)").length, + findAll('.sample-tree li:not(.jstree-hidden)').length, 1, - "Only matching node shown after search" + 'Only matching node shown after search' ); - await fillIn(".search-input", ""); + await fillIn('.search-input', ''); assert.equal( - findAll(".sample-tree li.jstree-hidden").length, + findAll('.sample-tree li.jstree-hidden').length, 0, - "All nodes are visible after clearing search" + 'All nodes are visible after clearing search' ); }); - test("Has dynamic demo", async function(assert) { + test('Has dynamic demo', async function (assert) { assert.expect(1); - await visit("/dynamic"); + await visit('/dynamic'); assert.equal( - findAll(".sample-tree").length, + findAll('.sample-tree').length, 1, - "Dynamic page contains a sample tree" + 'Dynamic page contains a sample tree' ); }); }); diff --git a/tests/dummy/app/controllers/application.js b/tests/dummy/app/controllers/application.js index fa4ba1e..3bed86b 100644 --- a/tests/dummy/app/controllers/application.js +++ b/tests/dummy/app/controllers/application.js @@ -1,3 +1,3 @@ -import Controller from "@ember/controller"; +import Controller from '@ember/controller'; -export default Controller.extend({}); +export default class Application extends Controller {} diff --git a/tests/dummy/app/dynamic/controller.js b/tests/dummy/app/dynamic/controller.js index 8e312dd..14e9377 100644 --- a/tests/dummy/app/dynamic/controller.js +++ b/tests/dummy/app/dynamic/controller.js @@ -1,88 +1,91 @@ -import { sort } from "@ember/object/computed"; -import Controller from "@ember/controller"; -import { computed } from "@ember/object"; -import { A } from "@ember/array"; -import ENV from "dummy/config/environment"; +import Controller from '@ember/controller'; +import { action } from '@ember/object'; +import { A } from '@ember/array'; +import ENV from 'dummy/config/environment'; +import { tracked } from '@glimmer/tracking'; -export default Controller.extend({ - jstreeActionReceiver: null, - jstreeSelectedNodes: A(), - sortedSelectedNodes: sort("jstreeSelectedNodes", function(a, b) { - if (a.text > b.text) { - return 1; - } else if (a.text < b.text) { - return -1; - } else { - return 0; - } - }), +export default class DynamicController extends Controller { + @tracked jstreeActionReceiver = null; + @tracked jstreeSelectedNodes = A(); - data: computed(() => ({ - url(node) { - if (ENV.environment === "production") { - return node.id === "#" - ? "/ember-cli-jstree/ajax_data_roots.json" - : "/ember-cli-jstree/ajax_data_children.json"; + get sortedSelectedNodes() { + return this.jstreeSelectedNodes.sort((a, b) => { + if (a.text > b.text) { + return 1; + } else if (a.text < b.text) { + return -1; } else { - return node.id === "#" - ? "/ajax_data_roots.json" - : "/ajax_data_children.json"; + return 0; } - }, - data(node) { - return { id: node.id }; - } - })), + }); + } - lastItemClicked: "", - treeReady: false, + get data() { + return { + url(node) { + if (ENV.environment === 'production') { + return node.id === '#' + ? '/ember-cli-jstree/ajax_data_roots.json' + : '/ember-cli-jstree/ajax_data_children.json'; + } else { + return node.id === '#' + ? '/ajax_data_roots.json' + : '/ajax_data_children.json'; + } + }, + data(node) { + return { id: node.id }; + }, + }; + } - plugins: "wholerow, dnd", - themes: computed(() => ({ - name: "default", - responsive: true - })), + @tracked lastItemClicked = ''; + @tracked treeReady = false; - actions: { - redraw() { - this.get("jstreeActionReceiver").send("redraw"); - }, + get plugins() { + return 'wholerow, dnd'; + } - destroy() { - this.get("jstreeActionReceiver").send("destroy"); - }, + get themes() { + return { + name: 'default', + responsive: true, + }; + } + + @action + redraw() { + this.jstreeActionReceiver.send('redraw'); + } - handleTreeSelectionDidChange() { - this.get("jsTreeActionReceiver").send("getSelected"); - }, + @action + destroyTree() { + this.jstreeActionReceiver.send('destroy'); + } - contextMenuReportClicked(node) { - this.set( - "lastItemClicked", - '"Report" item for node: <' + node.text + "> was clicked." - ); - }, + @action + handleTreeSelectionDidChange() { + this.jstreeActionReceiver.send('getSelected'); + } - addChildByText(nodeTextName) { - if (typeof nodeTextName !== "string") { - return; - } + @action + contextMenuReportClicked(node) { + this.lastItemClicked = + '"Report" item for node: <' + node.text + '> was clicked.'; + } - var data = this.get("data"); - data.forEach(function(node, index) { - if (typeof node === "object" && node["text"] === nodeTextName) { - data[index].children.push("added child"); - } - }); - this.set(data); - }, + @action + handleTreeDidBecomeReady() { + this.treeReady = true; + } - handleTreeDidBecomeReady() { - this.set("treeReady", true); - }, + @action + handleJstreeEventDidMoveNode(node) { + console.log(node); // eslint-disable-line no-console + } - handleJstreeEventDidMoveNode(node) { - console.log(node); // eslint-disable-line no-console - } + @action + updateField(field, value) { + this[field] = value; } -}); +} diff --git a/tests/dummy/app/dynamic/template.hbs b/tests/dummy/app/dynamic/template.hbs index 49b88bc..6d4ece7 100644 --- a/tests/dummy/app/dynamic/template.hbs +++ b/tests/dummy/app/dynamic/template.hbs @@ -1,53 +1,53 @@

Dynamic Tree

- {{ember-jstree - actionReceiver=jstreeActionReceiver - selectedNodes=jstreeSelectedNodes - themes=themes - data=data - plugins=plugins - contextMenuReportClicked=(action "contextMenuReportClicked") - eventDidBecomeReady=(action "handleTreeDidBecomeReady") - eventDidMoveNode=(action "handleJstreeEventDidMoveNode") - }} +
-
-

Tree Status

-

- Tree Ready? - - {{#if treeReady}} - Yes - {{else}} - No - {{/if}} - -

-
+
+

Tree Status

+

+ Tree Ready? + + {{#if this.treeReady}} + Yes + {{else}} + No + {{/if}} + +

+
-
+
-
-

Selected Items

- {{#if sortedSelectedNodes}} -
    - {{#each sortedSelectedNodes as |node|}} -
  • {{node.text}}
  • - {{/each}} -
- {{/if}} -
+
+

Selected Items

+ {{#if this.sortedSelectedNodes}} +
    + {{#each this.sortedSelectedNodes as |node|}} +
  • {{node.text}}
  • + {{/each}} +
+ {{/if}} +
-
+
-
-

Actions

- -

- -
+
+

Actions

+ +

+ +
diff --git a/tests/dummy/app/static/controller.js b/tests/dummy/app/static/controller.js index bc9be34..afa5b8a 100644 --- a/tests/dummy/app/static/controller.js +++ b/tests/dummy/app/static/controller.js @@ -1,140 +1,173 @@ -import { sort } from "@ember/object/computed"; -import Controller from "@ember/controller"; -import { A } from "@ember/array"; -import { computed, observer } from "@ember/object"; - -export default Controller.extend({ - jstreeActionReceiver: null, - jstreeSelectedNodes: A(), - jstreeBuffer: null, - jsonifiedBuffer: "", - searchTerm: "", - - sortedSelectedNodes: sort("jstreeSelectedNodes", function(a, b) { - if (a.text > b.text) { - return 1; - } else if (a.text < b.text) { - return -1; - } else { - return 0; +import Controller from '@ember/controller'; +import { A } from '@ember/array'; +import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; + +export default class StaticController extends Controller { + @tracked jstreeActionReceiver = null; + @tracked jstreeSelectedNodes = A(); + @tracked jstreeBuffer = null; + @tracked searchTerm = ''; + + @tracked _data = null; + + get sortedSelectedNodes() { + return this.jstreeSelectedNodes.sort((a, b) => { + if (a.text > b.text) { + return 1; + } else if (a.text < b.text) { + return -1; + } else { + return 0; + } + }); + } + + get data() { + if (this._data) { + return this._data; } - }), - - data: computed(() => [ - "Simple root node", - { - text: "Single child node (has tooltip)", - type: "single-child", - children: ["one child"], - a_attr: { class: "hint--top", "data-hint": "Use a_attr to add tooltips" } - }, - { - id: "rn2", - text: "Opened node (has tooltip)", - state: { - opened: true, - selected: true - }, - a_attr: { - class: "hint--bottom", - "data-hint": "This is a bottom mounted node tooltip" + + return [ + 'Simple root node', + { + text: 'Single child node (has tooltip)', + type: 'single-child', + children: ['one child'], + a_attr: { + class: 'hint--top', + 'data-hint': 'Use a_attr to add tooltips', + }, }, - children: [ - { - text: "Child 1" + { + id: 'rn2', + text: 'Opened node (has tooltip)', + state: { + opened: true, + selected: true, }, - "Child 2" - ] - } - ]), + a_attr: { + class: 'hint--bottom', + 'data-hint': 'This is a bottom mounted node tooltip', + }, + children: [ + { + text: 'Child 1', + }, + 'Child 2', + ], + }, + ]; + } - lastItemClicked: "", - treeReady: false, + @tracked lastItemClicked = ''; + @tracked treeReady = false; - plugins: "checkbox, wholerow, state, search, types, contextmenu", - themes: computed(() => ({ - name: "default", - responsive: true - })), + get plugins() { + return 'checkbox, wholerow, state, search, types, contextmenu'; + } - checkboxOptions: computed(() => ({ keep_selected_style: false })), - searchOptions: computed(() => ({ - show_only_matches: true - })), + get themes() { + return { + name: 'default', + responsive: true, + }; + } + + get checkboxOptions() { + return { keep_selected_style: false }; + } + get searchOptions() { + return { + show_only_matches: true, + }; + } - stateOptions: computed(() => ({ - key: "ember-cli-jstree-dummy" - })), + get stateOptions() { + return { + key: 'ember-cli-jstree-dummy', + }; + } - typesOptions: computed(() => ({ - "single-child": { - max_children: "1" - } - })), - - contextmenuOptions: computed(() => ({ - show_at_node: false, - items: { - reportClicked: { - label: "Report Clicked", - action: "contextMenuReportClicked" - } - } - })), + get typesOptions() { + return { + 'single-child': { + max_children: '1', + }, + }; + } + + get contextmenuOptions() { + return { + show_at_node: false, + items: { + reportClicked: { + label: 'Report Clicked', + action: 'contextMenuReportClicked', + }, + }, + }; + } - _jsonifyBufferWatcher: observer("jstreeBuffer", function() { - let b = this.get("jstreeBuffer"); + get jsonifiedBuffer() { + let b = this.jstreeBuffer; if (null !== b && b) { - this.set("jsonifiedBuffer", JSON.stringify(b)); + return JSON.stringify(b); } else { - this.set("jsonifiedBuffer", ""); + return ''; } - }), + } - actions: { - redraw() { - this.get("jstreeActionReceiver").send("redraw"); - }, + @action + redraw() { + this.jstreeActionReceiver.send('redraw'); + } + + @action + destroyTree() { + this.jstreeActionReceiver.send('destroy'); + } - destroy() { - this.get("jstreeActionReceiver").send("destroy"); - }, + @action + getNode(nodeId) { + this.jstreeActionReceiver.send('getNode', nodeId); + } + @action + handleGetNode(node) { + if (node) { + this.jstreeBuffer = node; + } + } - getNode(nodeId) { - this.get("jstreeActionReceiver").send("getNode", nodeId); - }, + @action + contextMenuReportClicked(node) { + this.lastItemClicked = + '"Report" item for node: <' + node.text + '> was clicked.'; + } + @action + addChildByText(nodeTextName) { + if (typeof nodeTextName !== 'string') { + return; + } - handleGetNode(node) { - if (node) { - this.set("jstreeBuffer", node); - } - }, - - contextMenuReportClicked(node) { - this.set( - "lastItemClicked", - '"Report" item for node: <' + node.text + "> was clicked." - ); - }, - - addChildByText(nodeTextName) { - if (typeof nodeTextName !== "string") { - return; + const data = this.data; + data.forEach(function (node, index) { + if (typeof node === 'object' && node.text === nodeTextName) { + data[index].children.push('added child'); } + }); + this._data = data; + this.redraw(); + } - var data = this.get("data"); - data.forEach(function(node, index) { - if (typeof node === "object" && node["text"] === nodeTextName) { - data[index].children.push("added child"); - } - }); - this.set("data", data); - this.send("redraw"); - }, - - handleTreeDidBecomeReady() { - this.set("treeReady", true); - } + @action + handleTreeDidBecomeReady() { + this.treeReady = true; + } + + @action + updateField(field, value) { + this[field] = value; } -}); +} diff --git a/tests/dummy/app/static/template.hbs b/tests/dummy/app/static/template.hbs index 5dc934b..4e92f95 100644 --- a/tests/dummy/app/static/template.hbs +++ b/tests/dummy/app/static/template.hbs @@ -1,82 +1,79 @@

Static Tree

- {{ember-jstree - actionReceiver=jstreeActionReceiver - selectedNodes=jstreeSelectedNodes - - data=data - plugins=plugins - themes=themes - - checkboxOptions=checkboxOptions - contextmenuOptions=contextmenuOptions - contextMenuReportClicked=(action "contextMenuReportClicked") - searchOptions=searchOptions - stateOptions=stateOptions - typesOptions=typesOptions - searchTerm=searchTerm - - eventDidBecomeReady=(action "handleTreeDidBecomeReady") - - actionGetNode=(action "handleGetNode") - }} +
-
-

Tree Status

-

- Tree Ready? - - {{#if treeReady}} - Yes - {{else}} - No - {{/if}} - -

-

Last Context Item Clicked: {{lastItemClicked}}

-
+
+

Tree Status

+

+ Tree Ready? + + {{#if this.treeReady}} + Yes + {{else}} + No + {{/if}} + +

+

Last Context Item Clicked: {{this.lastItemClicked}}

+
-
+
-
-

Selected Items

- {{#if sortedSelectedNodes}} -
    - {{#each sortedSelectedNodes as |node|}} -
  • {{node.text}}
  • - {{/each}} -
- {{/if}} -
+
+

Selected Items

+ {{#if this.sortedSelectedNodes}} +
    + {{#each this.sortedSelectedNodes as |node|}} +
  • {{node.text}}
  • + {{/each}} +
+ {{/if}} +
-
+
-
-

Actions

- -

- -

- -

- -
+
+

Actions

+ +

+ +

+ +

+ +
-
+
- + -
+
-
-

Buffer Console

-
{{jsonifiedBuffer}}
-
+
+

Buffer Console

+
{{this.jsonifiedBuffer}}
+
diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs index 60e35fd..9e58e4a 100644 --- a/tests/dummy/app/templates/application.hbs +++ b/tests/dummy/app/templates/application.hbs @@ -5,13 +5,13 @@

Examples

-
-
    - {{#link-to 'static' class="list-group-item"}}Static Tree{{/link-to}} - {{#link-to 'dynamic' class="list-group-item"}}Dynamic (AJAX-loaded) Tree{{/link-to}} -
-
-
- {{outlet}} -
+
+
    + Static Tree + Dynamic (AJAX-loaded) Tree +
+
+
+ {{outlet}} +
diff --git a/tests/dummy/config/environment.js b/tests/dummy/config/environment.js index f3fee60..a697812 100644 --- a/tests/dummy/config/environment.js +++ b/tests/dummy/config/environment.js @@ -1,11 +1,11 @@ -"use strict"; +'use strict'; module.exports = function (environment) { let ENV = { - modulePrefix: "dummy", + modulePrefix: 'dummy', environment, - rootURL: "/", - locationType: "auto", + rootURL: '/', + locationType: 'auto', EmberENV: { FEATURES: { // Here you can enable experimental features on an ember canary build @@ -23,7 +23,7 @@ module.exports = function (environment) { }, }; - if (environment === "development") { + if (environment === 'development') { // ENV.APP.LOG_RESOLVER = true; // ENV.APP.LOG_ACTIVE_GENERATION = true; // ENV.APP.LOG_TRANSITIONS = true; @@ -31,21 +31,21 @@ module.exports = function (environment) { // ENV.APP.LOG_VIEW_LOOKUPS = true; } - if (environment === "test") { + if (environment === 'test') { // Testem prefers this... - ENV.locationType = "none"; + ENV.locationType = 'none'; // keep test console output quieter ENV.APP.LOG_ACTIVE_GENERATION = false; ENV.APP.LOG_VIEW_LOOKUPS = false; - ENV.APP.rootElement = "#ember-testing"; + ENV.APP.rootElement = '#ember-testing'; ENV.APP.autoboot = false; } - if (environment === "production") { - ENV.locationType = "hash"; - ENV.rootURL = "/ember-cli-jstree/"; + if (environment === 'production') { + ENV.locationType = 'hash'; + ENV.rootURL = '/ember-cli-jstree/'; } return ENV; diff --git a/tests/dummy/config/targets.js b/tests/dummy/config/targets.js index 3406036..cc5778a 100644 --- a/tests/dummy/config/targets.js +++ b/tests/dummy/config/targets.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; const browsers = [ 'last 1 Chrome versions', diff --git a/tests/integration/components/ember-jstree-test.js b/tests/integration/components/ember-jstree-test.js index f810f5f..45cd426 100644 --- a/tests/integration/components/ember-jstree-test.js +++ b/tests/integration/components/ember-jstree-test.js @@ -1,4 +1,4 @@ -import { render, find } from '@ember/test-helpers'; +import { render, find, click } from '@ember/test-helpers'; import { setupRenderingTest } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; import jQuery from 'jquery'; @@ -8,6 +8,7 @@ module('Integration | Component | ember-jstree', function (hooks) { setupRenderingTest(hooks); test('events#eventDidOpen', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -17,17 +18,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidOpen=eventDidOpen - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('after_open.jstree', data); + jQuery.jstree.reference('.jstree').trigger('after_open.jstree', data); }); test('events#eventDidClose', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -37,17 +38,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidClose=eventDidClose - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('after_close.jstree', data); + jQuery.jstree.reference('.jstree').trigger('after_close.jstree', data); }); test('events#eventDidChange', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -57,17 +58,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidChange=eventDidChange - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('changed.jstree', data); + jQuery.jstree.reference('.jstree').trigger('changed.jstree', data); }); test('events#eventDidDehoverNode', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -77,17 +78,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidDehoverNode=eventDidDehoverNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('dehover_node.jstree', data); + jQuery.jstree.reference('.jstree').trigger('dehover_node.jstree', data); }); test('events#eventDidDeselectNode', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -97,17 +98,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidDeselectNode=eventDidDeselectNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('deselect_node.jstree', data); + jQuery.jstree.reference('.jstree').trigger('deselect_node.jstree', data); }); test('events#eventDidHoverNode', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -117,17 +118,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidHoverNode=eventDidHoverNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('hover_node.jstree', data); + jQuery.jstree.reference('.jstree').trigger('hover_node.jstree', data); }); test('events#eventDidInit', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -137,17 +138,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidInit=eventDidInit - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('init.jstree', data); + jQuery.jstree.reference('.jstree').trigger('init.jstree', data); }); test('events#eventIsLoading', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -157,17 +158,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventIsLoading=eventIsLoading - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('loading.jstree', data); + jQuery.jstree.reference('.jstree').trigger('loading.jstree', data); }); test('events#eventDidLoad', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -177,17 +178,15 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidLoad=eventDidLoad - }} + `); - - const tree = jQuery(find('.jstree')); - tree.trigger('loaded.jstree', data); }); test('events#eventDidBecomeReady', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -197,17 +196,15 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidBecomeReady=eventDidBecomeReady - }} + `); - - const tree = jQuery(find('.jstree')); - tree.trigger('ready.jstree', data); }); test('events#eventDidRedraw', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -217,17 +214,15 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidRedraw=eventDidRedraw - }} + `); - - const tree = jQuery(find('.jstree')); - tree.trigger('redraw.jstree', data); }); test('events#eventDidShowNode', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -237,17 +232,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidShowNode=eventDidShowNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('show_node.jstree', data); + jQuery.jstree.reference('.jstree').trigger('show_node.jstree', data); }); test('events#eventDidSelectNode', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -257,17 +252,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidSelectNode=eventDidSelectNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('select_node.jstree', data); + jQuery.jstree.reference('.jstree').trigger('select_node.jstree', data); }); test('events#eventDidDestroy', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -277,14 +272,15 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidDestroy=eventDidDestroy - }} + `); }); test('events#eventDidMoveNode', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -294,17 +290,17 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - eventDidMoveNode=eventDidMoveNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('move_node.jstree', data); + jQuery.jstree.reference('.jstree').trigger('move_node.jstree', data); }); test('events#eventDidDisableCheckbox', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -314,18 +310,18 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - plugins='checkbox' - eventDidDisableCheckbox=eventDidDisableCheckbox - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('disable_checkbox.jstree', data); + jQuery.jstree.reference('.jstree').trigger('disable_checkbox.jstree', data); }); test('events#eventDidEnableCheckbox', async function (assert) { + assert.expect(1); const data = { node: {} }; this.setProperties({ data, @@ -335,88 +331,104 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - plugins='checkbox' - eventDidEnableCheckbox=eventDidEnableCheckbox - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('enable_checkbox.jstree', data); + jQuery.jstree.reference('.jstree').trigger('enable_checkbox.jstree', data); }); test('events#eventDidCheckNode', async function (assert) { - const data = { node: {}, selected: {}, event: {} }; + assert.expect(3); + const data = { + node: {}, + selected: {}, + event: {}, + }; this.setProperties({ data, + checkboxOptions: { tie_selection: false }, eventDidCheckNode(node, selected, event) { - assert.equal(node, data.node); - assert.equal(selected, data.selected); - assert.equal(event, data.event); + assert.ok(node); + assert.strictEqual(selected[0], node.id); + assert.strictEqual(event.type, 'click'); }, }); await render(hbs` - {{ember-jstree - data=data - plugins='checkbox' - eventDidCheckNode=eventDidCheckNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('check_node.jstree', data); + await click('.jstree-last .jstree-anchor'); }); test('events#eventDidUncheckNode', async function (assert) { - const data = { node: {}, selected: {}, event: {} }; + assert.expect(3); + const data = { + node: { id: '#' }, + selected: {}, + event: {}, + }; this.setProperties({ data, + checkboxOptions: { tie_selection: false }, eventDidUncheckNode(node, selected, event) { - assert.equal(node, data.node); - assert.equal(selected, data.selected); - assert.equal(event, data.event); + assert.ok(node); + assert.strictEqual(selected.length, 0); + assert.strictEqual(event.type, 'click'); }, }); await render(hbs` - {{ember-jstree - data=data - plugins='checkbox' - eventDidUncheckNode=eventDidUncheckNode - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('uncheck_node.jstree', data); + await click('.jstree-last .jstree-anchor'); + await click('.jstree-last .jstree-anchor'); }); test('events#eventDidCheckAll', async function (assert) { + assert.expect(1); const data = { selected: {} }; this.setProperties({ data, + checkboxOptions: { tie_selection: false }, eventDidCheckAll(e) { assert.equal(e, data.selected); }, }); await render(hbs` - {{ember-jstree - data=data - plugins='checkbox' - eventDidCheckAll=eventDidCheckAll - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('check_all.jstree', data); + jQuery.jstree.reference('.jstree').trigger('check_all.jstree', data); }); test('events#eventDidUncheckAll', async function (assert) { + assert.expect(2); const data = { node: {}, selected: {} }; this.setProperties({ data, + checkboxOptions: { tie_selection: false }, eventDidUncheckAll(node, selected) { assert.equal(node, data.node); assert.equal(selected, data.selected); @@ -424,14 +436,14 @@ module('Integration | Component | ember-jstree', function (hooks) { }); await render(hbs` - {{ember-jstree - data=data - plugins='checkbox' - eventDidUncheckAll=eventDidUncheckAll - }} + `); - const tree = jQuery(find('.jstree')); - tree.trigger('uncheck_all.jstree', data); + jQuery.jstree.reference('.jstree').trigger('uncheck_all.jstree', data); }); }); From 77fb5832b1b091fe4b3c4d4eb861c0b230b231ad Mon Sep 17 00:00:00 2001 From: Tyler Bratton Date: Thu, 6 Mar 2025 11:30:03 -0500 Subject: [PATCH 4/4] Update jstree version to 3.3.17 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c45188d..370b7e6 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "ember-cli-babel": "^7.26.10", "ember-cli-htmlbars": "^5.7.2", "ember-lifeline": "^7.0.0", - "jstree": "^3.3.5" + "jstree": "^3.3.17" }, "ember": { "edition": "octane"