From 323f044c795c470f2b70a8d3247fb029bd9f5595 Mon Sep 17 00:00:00 2001 From: Gaurav Munjal Date: Mon, 2 Nov 2026 08:41:59 -0500 Subject: [PATCH] SCF-2416: keep Bootstrap 3 and subclassing, drop their deprecations This fork will not remove Bootstrap 3 support or subclassing of the component classes, so neither should warn that it is going away. Subclassing (port of upstream #2049, "Drop component subclassing deprecation", released in upstream 6.2.0): - addon/utils/deprecate-subclassing.js and every @deprecateSubclassing are removed, along with the '__ember-bootstrap_subclass' escape-hatch fields on the four internal subclasses that used it. - Unlike #2049, BsProgress and NavbarContent stay empty classes instead of becoming templateOnly(), which can't be subclassed. - The API docs no longer say subclassing "is generally not supported, and may break at any time"; they say it is supported. - The subclassing test now checks that a subclass of each of the 15 public components renders with no deprecations, replacing the two tests per component that asserted and silenced the deprecation. Bootstrap 3: index.js no longer warns at build time that Bootstrap 3 support "will be removed in ember-bootstrap v5". The Glyphicon warning for Bootstrap 4/5 stays; it is a configuration hint. README: the intro says Bootstrap 3, 4 or 5, and a new "About this fork" section explains git-tag installs, the independent version numbers, and that Bootstrap 3 and subclassing stay supported. Co-Authored-By: Claude Opus 5.5 --- README.md | 16 +++++++++- addon/components/bs-accordion.js | 4 +-- addon/components/bs-accordion/item.js | 2 -- addon/components/bs-accordion/item/title.js | 2 -- addon/components/bs-alert.js | 4 +-- addon/components/bs-button-group.js | 4 +-- addon/components/bs-button-group/button.js | 2 -- addon/components/bs-button.js | 4 +-- addon/components/bs-carousel.js | 4 +-- addon/components/bs-carousel/slide.js | 2 -- addon/components/bs-collapse.js | 4 +-- addon/components/bs-dropdown.js | 4 +-- addon/components/bs-dropdown/button.js | 4 +-- addon/components/bs-dropdown/menu.js | 2 -- addon/components/bs-dropdown/menu/divider.js | 2 -- addon/components/bs-dropdown/menu/item.js | 2 -- addon/components/bs-dropdown/toggle.js | 2 -- addon/components/bs-form.js | 4 +-- .../bs-form/element/control/checkbox.js | 2 -- .../bs-form/element/control/input.js | 2 -- .../bs-form/element/control/radio.js | 2 -- .../bs-form/element/control/switch.js | 2 -- .../bs-form/element/control/textarea.js | 2 -- addon/components/bs-form/element/errors.js | 2 -- .../bs-form/element/feedback-icon.js | 2 -- addon/components/bs-form/element/help-text.js | 2 -- addon/components/bs-form/element/label.js | 2 -- addon/components/bs-form/element/legend.js | 6 +--- addon/components/bs-modal.js | 4 +-- addon/components/bs-modal/dialog.js | 2 -- addon/components/bs-nav.js | 4 +-- addon/components/bs-nav/item.js | 2 -- addon/components/bs-navbar.js | 4 +-- addon/components/bs-navbar/content.js | 2 -- addon/components/bs-navbar/nav.js | 2 -- addon/components/bs-navbar/toggle.js | 2 -- addon/components/bs-popover.js | 4 +-- addon/components/bs-progress.js | 4 +-- addon/components/bs-progress/bar.js | 2 -- addon/components/bs-tab.js | 4 +-- addon/components/bs-tab/pane.js | 2 -- addon/components/bs-tooltip.js | 4 +-- addon/utils/deprecate-subclassing.js | 29 ------------------- index.js | 6 ---- .../components/subclassing-test.js | 21 +++++--------- 45 files changed, 39 insertions(+), 151 deletions(-) delete mode 100644 addon/utils/deprecate-subclassing.js diff --git a/README.md b/README.md index bb6de3fe0..9f803663c 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,26 @@ [![Ember Observer Score](http://emberobserver.com/badges/ember-bootstrap.svg)](http://emberobserver.com/addons/ember-bootstrap) [![npm version](https://badge.fury.io/js/ember-bootstrap.svg)](https://badge.fury.io/js/ember-bootstrap) -An [ember-cli](http://www.ember-cli.com) addon for using [Bootstrap](http://getbootstrap.com/) 3 or 4 in Ember applications. +An [ember-cli](http://www.ember-cli.com) addon for using [Bootstrap](http://getbootstrap.com/) 3, 4 or 5 in Ember applications. The addon includes the Bootstrap CSS (or Sass, Less) in your project (can be disabled). On top of that, it provides a set of native Ember components (no use of Bootstrap JavaScript!).

*See [www.ember-bootstrap.com](http://www.ember-bootstrap.com/) for full documentation.* +## About this fork + +This is SeeClickFix's fork of ember-bootstrap. It is installed from its git tags (for example +`"ember-bootstrap": "SeeClickFix/ember-bootstrap#v5.0.0"`), not from npm, and its version numbers are +independent of upstream's npm releases. + +This fork keeps supporting two things that upstream deprecated: + +* **Bootstrap 3.** Upstream deprecated it in 4.9.0 and removed it in 5.0.0. Here it stays supported + and tested, with no deprecation warning. +* **Subclassing the component classes.** Upstream deprecated extending from ember-bootstrap's + components in 4.0.0 (and dropped that deprecation again in 6.2.0). Here subclassing is supported + and raises no deprecation. + ## Installation In your application's directory: diff --git a/addon/components/bs-accordion.js b/addon/components/bs-accordion.js index e5085ca5f..b9c5325d1 100644 --- a/addon/components/bs-accordion.js +++ b/addon/components/bs-accordion.js @@ -1,6 +1,5 @@ import { action } from '@ember/object'; import Component from '@glimmer/component'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import { tracked } from '@glimmer/tracking'; /** @@ -31,14 +30,13 @@ import { tracked } from '@glimmer/tracking'; In the example above the first accordion item utilizes the yielded `change` action to add some custom behaviour. - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Accordion @namespace Components @extends Glimmer.Component @public */ -@deprecateSubclassing export default class Accordion extends Component { /** * The value of the currently selected accordion item. Set this to change selection programmatically. diff --git a/addon/components/bs-accordion/item.js b/addon/components/bs-accordion/item.js index 6956f71cf..acf83b957 100644 --- a/addon/components/bs-accordion/item.js +++ b/addon/components/bs-accordion/item.js @@ -2,7 +2,6 @@ import Component from '@glimmer/component'; import typeClass from 'ember-bootstrap/utils/cp/type-class'; import { getOwnConfig, macroCondition } from '@embroider/macros'; import { guidFor } from '@ember/object/internals'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import arg from '../../utils/decorators/arg'; /** @@ -15,7 +14,6 @@ import arg from '../../utils/decorators/arg'; @extends Ember.Component @public */ -@deprecateSubclassing export default class AccordionItem extends Component { /** * The title of the accordion item, displayed as a .panel-title element diff --git a/addon/components/bs-accordion/item/title.js b/addon/components/bs-accordion/item/title.js index 922aefc2b..442a13b06 100644 --- a/addon/components/bs-accordion/item/title.js +++ b/addon/components/bs-accordion/item/title.js @@ -1,6 +1,5 @@ import { action } from '@ember/object'; import Component from '@glimmer/component'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component for an accordion item title. @@ -12,7 +11,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @extends Glimmer.Component @public */ -@deprecateSubclassing export default class AccordionItemTitle extends Component { /** * @property collapsed diff --git a/addon/components/bs-alert.js b/addon/components/bs-alert.js index 0c36c0a24..2adcbac2a 100644 --- a/addon/components/bs-alert.js +++ b/addon/components/bs-alert.js @@ -3,7 +3,6 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { later, schedule } from '@ember/runloop'; import usesTransition from 'ember-bootstrap/utils/decorators/uses-transition'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import arg from 'ember-bootstrap/utils/decorators/arg'; /** @@ -36,14 +35,13 @@ import arg from 'ember-bootstrap/utils/decorators/arg'; The header is rendered using a `

` element by default. You can customize that one by setting `@headerTag` argument of ``. - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Alert @namespace Components @extends Glimmer.Component @public */ -@deprecateSubclassing export default class Alert extends Component { /** * A dismissible alert will have a close button in the upper right corner, that the user can click to dismiss diff --git a/addon/components/bs-button-group.js b/addon/components/bs-button-group.js index 03c20c34c..45c015c39 100644 --- a/addon/components/bs-button-group.js +++ b/addon/components/bs-button-group.js @@ -1,7 +1,6 @@ import { action } from '@ember/object'; import Component from '@glimmer/component'; import { A, isArray } from '@ember/array'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Bootstrap-style button group, that visually groups buttons, and optionally adds radio/checkbox like behaviour. @@ -54,14 +53,13 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; ``` - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class ButtonGroup @namespace Components @extends Glimmer.Component @public */ -@deprecateSubclassing export default class ButtonGroup extends Component { /** * @property buttonComponent diff --git a/addon/components/bs-button-group/button.js b/addon/components/bs-button-group/button.js index 39ba35104..c072aa3d5 100644 --- a/addon/components/bs-button-group/button.js +++ b/addon/components/bs-button-group/button.js @@ -10,8 +10,6 @@ import Button from 'ember-bootstrap/components/bs-button'; @private */ export default class ButtonGroupButton extends Button { - '__ember-bootstrap_subclass' = true; - /** * @property groupValue * @private diff --git a/addon/components/bs-button.js b/addon/components/bs-button.js index 30fd12ba9..fb5181f98 100644 --- a/addon/components/bs-button.js +++ b/addon/components/bs-button.js @@ -3,7 +3,6 @@ import { action } from '@ember/object'; import { warn } from '@ember/debug'; import Component from '@glimmer/component'; import arg from 'ember-bootstrap/utils/decorators/arg'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import { DEBUG } from '@glimmer/env'; /** @@ -91,14 +90,13 @@ import { DEBUG } from '@glimmer/env'; You can `reset` the state represented by these properties and used for button's text by setting `reset` property to `true`. - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Button @namespace Components @extends Glimmer.Component @public */ -@deprecateSubclassing export default class Button extends Component { /** * Default label of the button. Not need if used as a block component diff --git a/addon/components/bs-carousel.js b/addon/components/bs-carousel.js index d8423994c..798814738 100644 --- a/addon/components/bs-carousel.js +++ b/addon/components/bs-carousel.js @@ -10,7 +10,6 @@ import { task, timeout } from 'ember-concurrency'; import RSVP from 'rsvp'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; import { equal } from '@ember/object/computed'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Ember implementation of Bootstrap's Carousel. Supports all original features but API is partially different: @@ -55,7 +54,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; | Wrap | wrap slides, cycles without stopping at first or last slide. | ``` - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Carousel @namespace Components @@ -63,7 +62,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class Carousel extends Component.extend(ComponentParent) { tabindex = '1'; diff --git a/addon/components/bs-carousel/slide.js b/addon/components/bs-carousel/slide.js index 39181e279..ce16e8dc3 100644 --- a/addon/components/bs-carousel/slide.js +++ b/addon/components/bs-carousel/slide.js @@ -5,7 +5,6 @@ import ComponentChild from 'ember-bootstrap/mixins/component-child'; import { next } from '@ember/runloop'; import overrideableCP from 'ember-bootstrap/utils/cp/overrideable'; import { addObserver } from '@ember/object/observers'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import trackElement from 'ember-bootstrap/utils/track-element'; /** @@ -19,7 +18,6 @@ import trackElement from 'ember-bootstrap/utils/track-element'; @public */ @tagName('') -@deprecateSubclassing export default class CarouselSlide extends Component.extend(ComponentChild) { /** * @property _element diff --git a/addon/components/bs-collapse.js b/addon/components/bs-collapse.js index ae2baef48..a99b40f67 100644 --- a/addon/components/bs-collapse.js +++ b/addon/components/bs-collapse.js @@ -3,7 +3,6 @@ import Component from '@glimmer/component'; import { isNone } from '@ember/utils'; import { next } from '@ember/runloop'; import transitionEnd from 'ember-bootstrap/utils/transition-end'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import trackElement from 'ember-bootstrap/utils/track-element'; import arg from '../utils/decorators/arg'; import { tracked } from '@glimmer/tracking'; @@ -22,14 +21,13 @@ import { tracked } from '@glimmer/tracking'; ``` - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Collapse @namespace Components @extends Glimmer.Component @public */ -@deprecateSubclassing export default class Collapse extends Component { /** * @property _element diff --git a/addon/components/bs-dropdown.js b/addon/components/bs-dropdown.js index b1a0e47da..e5e86d162 100644 --- a/addon/components/bs-dropdown.js +++ b/addon/components/bs-dropdown.js @@ -3,7 +3,6 @@ import { action, computed } from '@ember/object'; import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; import { assert } from '@ember/debug'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; const ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key const SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key @@ -164,7 +163,7 @@ const SUPPORTED_KEYCODES = [ESCAPE_KEYCODE, ARROW_DOWN_KEYCODE, ARROW_UP_KEYCODE version does. This also allows you to set `renderInPlace=false` on the menu component to render it in a wormhole, which you might want to do if you experience clipping issues by an outer `overflow: hidden` element. - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Dropdown @namespace Components @@ -172,7 +171,6 @@ const SUPPORTED_KEYCODES = [ESCAPE_KEYCODE, ARROW_DOWN_KEYCODE, ARROW_UP_KEYCODE @public s*/ @tagName('') -@deprecateSubclassing export default class Dropdown extends Component { /** * The tag name used for the dropdown element. diff --git a/addon/components/bs-dropdown/button.js b/addon/components/bs-dropdown/button.js index 46ceb2091..8f194f296 100644 --- a/addon/components/bs-dropdown/button.js +++ b/addon/components/bs-dropdown/button.js @@ -10,6 +10,4 @@ import Button from 'ember-bootstrap/components/bs-button'; @extends Components.Button @public */ -export default class DropdownButton extends Button { - '__ember-bootstrap_subclass' = true; -} +export default class DropdownButton extends Button {} diff --git a/addon/components/bs-dropdown/menu.js b/addon/components/bs-dropdown/menu.js index f3426fa81..884099513 100644 --- a/addon/components/bs-dropdown/menu.js +++ b/addon/components/bs-dropdown/menu.js @@ -4,7 +4,6 @@ import Component from '@ember/component'; import { next } from '@ember/runloop'; import { getDestinationElement } from 'ember-bootstrap/utils/dom'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import trackElement from 'ember-bootstrap/utils/track-element'; /** @@ -18,7 +17,6 @@ import trackElement from 'ember-bootstrap/utils/track-element'; @public */ @tagName('') -@deprecateSubclassing export default class DropdownMenu extends Component { /** * @property _element diff --git a/addon/components/bs-dropdown/menu/divider.js b/addon/components/bs-dropdown/menu/divider.js index ca4a3ed67..4a6e05be5 100644 --- a/addon/components/bs-dropdown/menu/divider.js +++ b/addon/components/bs-dropdown/menu/divider.js @@ -1,6 +1,5 @@ import Component from '@ember/component'; import { tagName } from '@ember-decorators/component'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component for a dropdown menu divider. @@ -13,5 +12,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class DropdownMenuDivider extends Component {} diff --git a/addon/components/bs-dropdown/menu/item.js b/addon/components/bs-dropdown/menu/item.js index 67e41b0ef..cab2a895c 100644 --- a/addon/components/bs-dropdown/menu/item.js +++ b/addon/components/bs-dropdown/menu/item.js @@ -1,6 +1,5 @@ import Component from '@ember/component'; import { tagName } from '@ember-decorators/component'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component for a dropdown menu item. @@ -13,5 +12,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class DropdownMenuItem extends Component {} diff --git a/addon/components/bs-dropdown/toggle.js b/addon/components/bs-dropdown/toggle.js index 03c82a484..e8a23ae49 100644 --- a/addon/components/bs-dropdown/toggle.js +++ b/addon/components/bs-dropdown/toggle.js @@ -2,7 +2,6 @@ import { tagName } from '@ember-decorators/component'; import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; import { computed, action } from '@ember/object'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Anchor element that triggers the parent dropdown to open. @@ -16,7 +15,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @publicø */ @tagName('') -@deprecateSubclassing export default class DropdownToggle extends Component { /** * @property inNav diff --git a/addon/components/bs-form.js b/addon/components/bs-form.js index b93fd6770..d71b8c7b8 100644 --- a/addon/components/bs-form.js +++ b/addon/components/bs-form.js @@ -9,7 +9,6 @@ import RSVP from 'rsvp'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; import { macroCondition, getOwnConfig } from '@embroider/macros'; import { DEBUG } from '@glimmer/env'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Render a form with the appropriate Bootstrap layout class (see `formLayout`). @@ -120,7 +119,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; The submission state is reset as soon as any value of a form element changes. Additionally it can be reset programatically by calling the yielded `resetSubmissionState` function. - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Form @namespace Components @@ -128,7 +127,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class Form extends Component { /** * Bootstrap form class name (computed) diff --git a/addon/components/bs-form/element/control/checkbox.js b/addon/components/bs-form/element/control/checkbox.js index 086757ee8..2bbadc9ea 100644 --- a/addon/components/bs-form/element/control/checkbox.js +++ b/addon/components/bs-form/element/control/checkbox.js @@ -1,7 +1,6 @@ import { action } from '@ember/object'; import { tagName } from '@ember-decorators/component'; import Control from '../control'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementControlCheckbox extends Control { @action handleClick(event) { diff --git a/addon/components/bs-form/element/control/input.js b/addon/components/bs-form/element/control/input.js index cc50f597f..82e9365c6 100644 --- a/addon/components/bs-form/element/control/input.js +++ b/addon/components/bs-form/element/control/input.js @@ -3,7 +3,6 @@ import { action } from '@ember/object'; import Control from '../control'; import sizeClass from 'ember-bootstrap/utils/cp/size-class'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -13,7 +12,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementControlInput extends Control { /** * @property type diff --git a/addon/components/bs-form/element/control/radio.js b/addon/components/bs-form/element/control/radio.js index ffe686662..7f49c180d 100644 --- a/addon/components/bs-form/element/control/radio.js +++ b/addon/components/bs-form/element/control/radio.js @@ -1,7 +1,6 @@ import { tagName } from '@ember-decorators/component'; import Control from '../control'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementControlRadio extends Control { /** * @property inline diff --git a/addon/components/bs-form/element/control/switch.js b/addon/components/bs-form/element/control/switch.js index e9123f77e..ceb81f316 100644 --- a/addon/components/bs-form/element/control/switch.js +++ b/addon/components/bs-form/element/control/switch.js @@ -1,7 +1,6 @@ import { action } from '@ember/object'; import { tagName } from '@ember-decorators/component'; import Control from '../control'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementControlSwitch extends Control { @action handleClick(event) { diff --git a/addon/components/bs-form/element/control/textarea.js b/addon/components/bs-form/element/control/textarea.js index 2f72e1a9a..2b4b1f5fb 100644 --- a/addon/components/bs-form/element/control/textarea.js +++ b/addon/components/bs-form/element/control/textarea.js @@ -1,7 +1,6 @@ import { action } from '@ember/object'; import { tagName } from '@ember-decorators/component'; import Control from '../control'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementControlTextarea extends Control { @action handleChange(event) { diff --git a/addon/components/bs-form/element/errors.js b/addon/components/bs-form/element/errors.js index b1288223e..21c0d218e 100644 --- a/addon/components/bs-form/element/errors.js +++ b/addon/components/bs-form/element/errors.js @@ -1,7 +1,6 @@ import { tagName } from '@ember-decorators/component'; import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @class FormElementErrors @@ -10,7 +9,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementErrors extends Component { /** * @property show diff --git a/addon/components/bs-form/element/feedback-icon.js b/addon/components/bs-form/element/feedback-icon.js index 401493679..381ea6bdb 100644 --- a/addon/components/bs-form/element/feedback-icon.js +++ b/addon/components/bs-form/element/feedback-icon.js @@ -1,7 +1,6 @@ import { tagName } from '@ember-decorators/component'; import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -11,7 +10,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementFeedbackIcon extends Component { /** * @property show diff --git a/addon/components/bs-form/element/help-text.js b/addon/components/bs-form/element/help-text.js index 12a6a8b9d..efcc9cc2f 100644 --- a/addon/components/bs-form/element/help-text.js +++ b/addon/components/bs-form/element/help-text.js @@ -1,6 +1,5 @@ import { tagName } from '@ember-decorators/component'; import Component from '@ember/component'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -10,5 +9,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementHelpText extends Component {} diff --git a/addon/components/bs-form/element/label.js b/addon/components/bs-form/element/label.js index e9a9ff48d..5ed27f86f 100644 --- a/addon/components/bs-form/element/label.js +++ b/addon/components/bs-form/element/label.js @@ -4,7 +4,6 @@ import { equal } from '@ember/object/computed'; import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; import { isBlank } from '@ember/utils'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -14,7 +13,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @private */ @tagName('') -@deprecateSubclassing export default class FormElementLabel extends Component { /** * @property label diff --git a/addon/components/bs-form/element/legend.js b/addon/components/bs-form/element/legend.js index 52c038654..25cc7d2fa 100644 --- a/addon/components/bs-form/element/legend.js +++ b/addon/components/bs-form/element/legend.js @@ -1,9 +1,5 @@ import { tagName } from '@ember-decorators/component'; import FormElementLabel from 'ember-bootstrap/components/bs-form/element/label'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @tagName('') -@deprecateSubclassing -export default class FormElementLegend extends FormElementLabel { - '__ember-bootstrap_subclass' = true; -} +export default class FormElementLegend extends FormElementLabel {} diff --git a/addon/components/bs-modal.js b/addon/components/bs-modal.js index 7d8b8fb2a..760738910 100644 --- a/addon/components/bs-modal.js +++ b/addon/components/bs-modal.js @@ -7,7 +7,6 @@ import transitionEnd from 'ember-bootstrap/utils/transition-end'; import { getDestinationElement } from 'ember-bootstrap/utils/dom'; import usesTransition from 'ember-bootstrap/utils/decorators/uses-transition'; import isFastBoot from 'ember-bootstrap/utils/is-fastboot'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import arg from '../utils/decorators/arg'; import { tracked } from '@glimmer/tracking'; import trackElement from 'ember-bootstrap/utils/track-element'; @@ -55,14 +54,13 @@ function afterRender() { See the documentation of the [bs-modal-simple](Components.ModalSimple.html) component for further examples. - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Modal @namespace Components @extends Glimmer.Component @public */ -@deprecateSubclassing export default class Modal extends Component { @service('-document') document; diff --git a/addon/components/bs-modal/dialog.js b/addon/components/bs-modal/dialog.js index 049e3615c..09683397b 100644 --- a/addon/components/bs-modal/dialog.js +++ b/addon/components/bs-modal/dialog.js @@ -2,7 +2,6 @@ import { action } from '@ember/object'; import { isBlank } from '@ember/utils'; import Component from '@glimmer/component'; import { next } from '@ember/runloop'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import trackElement from 'ember-bootstrap/utils/track-element'; import { tracked } from '@glimmer/tracking'; @@ -14,7 +13,6 @@ import { tracked } from '@glimmer/tracking'; @extends Glimmer.Component @private */ -@deprecateSubclassing export default class ModalDialog extends Component { /** * @property id diff --git a/addon/components/bs-nav.js b/addon/components/bs-nav.js index 1f2e4c369..189e9e361 100644 --- a/addon/components/bs-nav.js +++ b/addon/components/bs-nav.js @@ -2,7 +2,6 @@ import { tagName } from '@ember-decorators/component'; import { computed } from '@ember/object'; import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component to generate [bootstrap navs](http://getbootstrap.com/components/#nav) @@ -75,7 +74,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; The `fill` styling is only available with Bootstrap 4 - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Nav @namespace Components @@ -84,7 +83,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; */ @tagName('') -@deprecateSubclassing export default class Nav extends Component { @computed('type') get typeClass() { diff --git a/addon/components/bs-nav/item.js b/addon/components/bs-nav/item.js index 0f273f4b2..188fa9d4d 100644 --- a/addon/components/bs-nav/item.js +++ b/addon/components/bs-nav/item.js @@ -8,7 +8,6 @@ import LinkComponent from 'ember-bootstrap/components/bs-link-to'; import ComponentParent from 'ember-bootstrap/mixins/component-parent'; import overrideableCP from 'ember-bootstrap/utils/cp/overrideable'; import { assert } from '@ember/debug'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -21,7 +20,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class NavItem extends Component.extend(ComponentParent) { /** * Render the nav item as disabled (see [Bootstrap docs](http://getbootstrap.com/components/#nav-disabled-links)). diff --git a/addon/components/bs-navbar.js b/addon/components/bs-navbar.js index b7fd83a5f..a8573aa30 100644 --- a/addon/components/bs-navbar.js +++ b/addon/components/bs-navbar.js @@ -7,7 +7,6 @@ import defaultValue from 'ember-bootstrap/utils/default-decorator'; import { assert } from '@ember/debug'; import { macroCondition, getOwnConfig } from '@embroider/macros'; import { isBlank } from '@ember/utils'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component to generate [Bootstrap navbars](http://getbootstrap.com/components/#navbar). @@ -96,7 +95,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; Bootstrap 4 navbars are fluid by default without the need for an additional container. An additional container is added like with Bootstrap 3 if `fluid` is `false`. - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Navbar @namespace Components @@ -104,7 +103,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class Navbar extends Component { /** * Manages the state for the responsive menu between the toggle and the content. diff --git a/addon/components/bs-navbar/content.js b/addon/components/bs-navbar/content.js index e6f3c3228..7a81f0dff 100644 --- a/addon/components/bs-navbar/content.js +++ b/addon/components/bs-navbar/content.js @@ -1,6 +1,5 @@ import { tagName } from '@ember-decorators/component'; import Component from '@ember/component'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** * Component to wrap the collapsible content of a [Components.Navbar](Components.Navbar.html) component. @@ -12,5 +11,4 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; * @public */ @tagName('') -@deprecateSubclassing export default class NavbarContent extends Component {} diff --git a/addon/components/bs-navbar/nav.js b/addon/components/bs-navbar/nav.js index 379833b16..14ead4ce7 100644 --- a/addon/components/bs-navbar/nav.js +++ b/addon/components/bs-navbar/nav.js @@ -14,8 +14,6 @@ import defaultValue from 'ember-bootstrap/utils/default-decorator'; * @public */ export default class NavbarNav extends BsNavComponent { - '__ember-bootstrap_subclass' = true; - @defaultValue justified = false; diff --git a/addon/components/bs-navbar/toggle.js b/addon/components/bs-navbar/toggle.js index 6d6e38612..65847c474 100644 --- a/addon/components/bs-navbar/toggle.js +++ b/addon/components/bs-navbar/toggle.js @@ -2,7 +2,6 @@ import { action } from '@ember/object'; import { tagName } from '@ember-decorators/component'; import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** * Component to implement the responsive menu toggle behavior in a [Components.Navbar](Components.Navbar.html) @@ -19,7 +18,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; * @public */ @tagName('') -@deprecateSubclassing export default class NavbarToggle extends Component { @defaultValue collapsed = true; diff --git a/addon/components/bs-popover.js b/addon/components/bs-popover.js index 4de4345b1..6aa618b47 100644 --- a/addon/components/bs-popover.js +++ b/addon/components/bs-popover.js @@ -1,6 +1,5 @@ import ContextualHelp from './bs-contextual-help'; import arg from '../utils/decorators/arg'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component that implements Bootstrap [popovers](http://getbootstrap.com/javascript/#popovers). @@ -62,14 +61,13 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; * `onHide` * `onHidden` - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Popover @namespace Components @extends Components.ContextualHelp @public */ -@deprecateSubclassing export default class Popover extends ContextualHelp { /** * @property placement diff --git a/addon/components/bs-progress.js b/addon/components/bs-progress.js index c2f472225..f6f27e014 100644 --- a/addon/components/bs-progress.js +++ b/addon/components/bs-progress.js @@ -1,6 +1,5 @@ import { tagName } from '@ember-decorators/component'; import Component from '@ember/component'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component to display a Bootstrap progress bar, see http://getbootstrap.com/components/#progress. @@ -30,7 +29,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; ``` - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Progress @namespace Components @@ -38,7 +37,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class Progress extends Component { /** * @property progressBarComponent diff --git a/addon/components/bs-progress/bar.js b/addon/components/bs-progress/bar.js index a4f1cc48f..a39a0300c 100644 --- a/addon/components/bs-progress/bar.js +++ b/addon/components/bs-progress/bar.js @@ -4,7 +4,6 @@ import Component from '@ember/component'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; import typeClass from 'ember-bootstrap/utils/cp/type-class'; import { macroCondition, getOwnConfig } from '@embroider/macros'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** @@ -16,7 +15,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class ProgressBar extends Component { /** * The lower limit of the value range diff --git a/addon/components/bs-tab.js b/addon/components/bs-tab.js index 205ac6c9e..42981f673 100644 --- a/addon/components/bs-tab.js +++ b/addon/components/bs-tab.js @@ -8,7 +8,6 @@ import ComponentParent from 'ember-bootstrap/mixins/component-parent'; import TabPane from 'ember-bootstrap/components/bs-tab/pane'; import listenTo from 'ember-bootstrap/utils/cp/listen-to'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Tab component for dynamic tab functionality that mimics the behaviour of Bootstrap's tab.js plugin, @@ -106,7 +105,7 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; ``` - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Tab @namespace Components @@ -115,7 +114,6 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; @public */ @tagName('') -@deprecateSubclassing export default class Tab extends Component.extend(ComponentParent) { /** * Type of nav, either "pills" or "tabs" diff --git a/addon/components/bs-tab/pane.js b/addon/components/bs-tab/pane.js index 42cb4ea5b..4462eb971 100644 --- a/addon/components/bs-tab/pane.js +++ b/addon/components/bs-tab/pane.js @@ -8,7 +8,6 @@ import transitionEnd from 'ember-bootstrap/utils/transition-end'; import usesTransition from 'ember-bootstrap/utils/cp/uses-transition'; import defaultValue from 'ember-bootstrap/utils/default-decorator'; import { guidFor } from '@ember/object/internals'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; import trackElement from 'ember-bootstrap/utils/track-element'; /** @@ -22,7 +21,6 @@ import trackElement from 'ember-bootstrap/utils/track-element'; @public */ @tagName('') -@deprecateSubclassing export default class TabPane extends Component.extend(ComponentChild) { /** * @property id diff --git a/addon/components/bs-tooltip.js b/addon/components/bs-tooltip.js index e01986736..23c298dcf 100644 --- a/addon/components/bs-tooltip.js +++ b/addon/components/bs-tooltip.js @@ -1,5 +1,4 @@ import ContextualHelp from './bs-contextual-help'; -import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; /** Component that implements Bootstrap [tooltips](http://getbootstrap.com/javascript/#tooltips). @@ -71,14 +70,13 @@ import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing'; * `onHide` * `onHidden` - *Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.* + *Besides invoking the component in a template as shown above, extending from it (subclassing) is supported as well.* @class Tooltip @namespace Components @extends Components.ContextualHelp @public */ -@deprecateSubclassing export default class Tooltip extends ContextualHelp { /** * @property elementComponent diff --git a/addon/utils/deprecate-subclassing.js b/addon/utils/deprecate-subclassing.js deleted file mode 100644 index f4d193188..000000000 --- a/addon/utils/deprecate-subclassing.js +++ /dev/null @@ -1,29 +0,0 @@ -import { DEBUG } from '@glimmer/env'; -import { deprecate } from '@ember/debug'; -import { next } from '@ember/runloop'; - -export default function deprecateSubclassing(target) { - if (DEBUG) { - const wrapperClass = class extends target { - constructor() { - super(...arguments); - // we need to delay the deprecation check, as the __ember-bootstrap_subclass class field will only be set *after* the constructor - next(() => { - deprecate( - `Extending from ember-bootstrap component classes is not supported, and might break anytime. Detected subclassing of component.`, - // the `__ember-bootstrap_subclass` flag is an escape hatch for "privileged" addons like validations addons that currently still have to rely on subclassing - wrapperClass === this.constructor || this['__ember-bootstrap_subclass'] === true, - { - id: `ember-bootstrap.subclassing#${target.name}`, - until: '5.0.0', - since: '4.0.0', - for: 'ember-bootstrap', - } - ); - }); - } - }; - - return wrapperClass; - } -} diff --git a/index.js b/index.js index 44beda48f..fea10ce32 100644 --- a/index.js +++ b/index.js @@ -57,12 +57,6 @@ module.exports = { let options = Object.assign({}, defaultOptions, app.options['ember-bootstrap']); - if (options.bootstrapVersion === 3) { - this.warn( - 'Support for Bootstrap 3 has been deprecated and will be removed in ember-bootstrap v5! Consider migrating to Bootstrap v4 or v5!' - ); - } - if (options.bootstrapVersion >= 4 && options.importBootstrapFont) { this.warn( 'Inclusion of the Glyphicon font is only supported for Bootstrap 3. ' + diff --git a/tests/integration/components/subclassing-test.js b/tests/integration/components/subclassing-test.js index bed3c2c13..18a9e0bc9 100644 --- a/tests/integration/components/subclassing-test.js +++ b/tests/integration/components/subclassing-test.js @@ -89,27 +89,20 @@ module('Integration | subclassing', function (hooks) { tests.forEach(({ name, clazz }) => { module(name, function () { - test('it should not be subclassed', async function (assert) { - class MyClass extends clazz {} - - this.owner.register('component:test-component', MyClass); - - await render(hbs``); - - assert.deprecationsInclude( - `Extending from ember-bootstrap component classes is not supported, and might break anytime. Detected subclassing of <${name}> component.` - ); - }); - - test('subclass warning can be silenced', async function (assert) { + test('it can be subclassed without deprecations', async function (assert) { + let constructed = false; class MyClass extends clazz { - '__ember-bootstrap_subclass' = true; + constructor() { + super(...arguments); + constructed = true; + } } this.owner.register('component:test-component', MyClass); await render(hbs``); + assert.true(constructed, 'the subclass is instantiated'); assert.deprecations(0); }); });