mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 02:30:57 +08:00
DEV: Drop Ember 3 feature flag
This commit is contained in:
parent
2018cd3b62
commit
542cb22fd4
69
.github/workflows/ember-version-enforcement.yml
vendored
69
.github/workflows/ember-version-enforcement.yml
vendored
|
@ -1,69 +0,0 @@
|
||||||
# This workflow is designed to stop us accidently committing the lockfile/packagejson symlink changes
|
|
||||||
# which would cause the default Ember version to change.
|
|
||||||
|
|
||||||
name: Ember Version Enforcement
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: yarn
|
|
||||||
- name: Yarn install
|
|
||||||
run: |
|
|
||||||
cd app/assets/javascripts/discourse
|
|
||||||
yarn install
|
|
||||||
- name: "Check default ember version"
|
|
||||||
working-directory: app/assets/javascripts/discourse
|
|
||||||
run: |
|
|
||||||
node -e '
|
|
||||||
const version = require("ember-source/package.json").version;
|
|
||||||
console.log("Ember version is", version);
|
|
||||||
if(version.split(".")[0] !== "5"){
|
|
||||||
console.log(`Ember has unexpectedly been downgraded to version ${version}. If this is intentional, remove this github workflow.`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
'
|
|
||||||
- name: Downgrade ember
|
|
||||||
run: |
|
|
||||||
script/switch_ember_version 3
|
|
||||||
cd app/assets/javascripts/discourse
|
|
||||||
yarn install
|
|
||||||
- name: "Check upgraded version"
|
|
||||||
working-directory: app/assets/javascripts/discourse
|
|
||||||
run: |
|
|
||||||
node -e '
|
|
||||||
const version = require("ember-source/package.json").version;
|
|
||||||
console.log("Ember version is", version);
|
|
||||||
if(version.split(".")[0] !== "3"){
|
|
||||||
console.log(`Expected Ember 3, but found ${version}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
'
|
|
||||||
- name: "Revert ember downgrade"
|
|
||||||
run: |
|
|
||||||
script/switch_ember_version 5
|
|
||||||
- name: "Ensure no diff"
|
|
||||||
run: |
|
|
||||||
if [ ! -z "$(git status --porcelain)" ]; then
|
|
||||||
echo "Working directory was not clean after upgrading/downgrading ember. Perhaps a lockfile is out-of-date. Run this command to re-sync:"
|
|
||||||
echo " script/regen_ember_3_lockfile"
|
|
||||||
echo
|
|
||||||
echo "Current diff:"
|
|
||||||
echo "---------------------------------------------"
|
|
||||||
git -c color.ui=always diff
|
|
||||||
exit 1
|
|
||||||
fi
|
|
38
.github/workflows/ember-version-lockfiles.yml
vendored
38
.github/workflows/ember-version-lockfiles.yml
vendored
|
@ -1,38 +0,0 @@
|
||||||
# This workflow will run on dependabot pull requests to ensure that they update both the ember3 and ember5 lockfiles
|
|
||||||
|
|
||||||
name: Ember Version Lockfiles
|
|
||||||
|
|
||||||
on:
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
help_dependabot:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ github.actor == 'dependabot[bot]' }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.head_ref }}
|
|
||||||
- name: Move lockfile to correct location
|
|
||||||
run: |
|
|
||||||
# Dependabot gets confused by the symlinks and dumps the updated lockfile in the root of the repo.
|
|
||||||
# Let's move it back to the correct location.
|
|
||||||
if [[ -f yarn-ember5.lock ]]; then
|
|
||||||
mv yarn-ember5.lock app/assets/javascripts/yarn-ember5.lock
|
|
||||||
fi
|
|
||||||
- name: Update ember3 lockfile
|
|
||||||
run: script/regen_ember_3_lockfile
|
|
||||||
- name: Push changes
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
if [ ! -z "$(git status --porcelain)" ]; then
|
|
||||||
git config --global user.email "build@discourse.org"
|
|
||||||
git config --global user.name "discoursebuild"
|
|
||||||
git add .
|
|
||||||
git commit -m "Update lockfiles for ember version flag"
|
|
||||||
git push
|
|
||||||
fi
|
|
17
.github/workflows/tests.yml
vendored
17
.github/workflows/tests.yml
vendored
|
@ -22,7 +22,7 @@ permissions:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
|
if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
|
||||||
name: ${{ matrix.target }} ${{ matrix.build_type }}${{ !matrix.updated_ember && ' (Ember 3)' || '' }} # Update fetch-job-id step if changing this
|
name: ${{ matrix.target }} ${{ matrix.build_type }} # Update fetch-job-id step if changing this
|
||||||
runs-on: ${{ (matrix.build_type == 'annotations') && 'ubuntu-latest' || 'ubuntu-20.04-8core' }}
|
runs-on: ${{ (matrix.build_type == 'annotations') && 'ubuntu-latest' || 'ubuntu-20.04-8core' }}
|
||||||
container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }}${{ (matrix.ruby == '3.1') && '-ruby-3.1.0' || '' }}
|
container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }}${{ (matrix.ruby == '3.1') && '-ruby-3.1.0' || '' }}
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
|
@ -35,7 +35,6 @@ jobs:
|
||||||
USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' || matrix.build_type == 'system' }}
|
USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' || matrix.build_type == 'system' }}
|
||||||
CAPYBARA_DEFAULT_MAX_WAIT_TIME: 10
|
CAPYBARA_DEFAULT_MAX_WAIT_TIME: 10
|
||||||
MINIO_RUNNER_LOG_LEVEL: DEBUG
|
MINIO_RUNNER_LOG_LEVEL: DEBUG
|
||||||
EMBER_VERSION: ${{ (matrix.updated_ember && '5') || '3' }}
|
|
||||||
DISCOURSE_TURBO_RSPEC_RETRY_AND_LOG_FLAKY_TESTS: ${{ (matrix.build_type == 'system' || matrix.build_type == 'backend') && github.ref == 'refs/main/head' }}
|
DISCOURSE_TURBO_RSPEC_RETRY_AND_LOG_FLAKY_TESTS: ${{ (matrix.build_type == 'system' || matrix.build_type == 'backend') && github.ref == 'refs/main/head' }}
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
|
@ -45,7 +44,6 @@ jobs:
|
||||||
build_type: [backend, frontend, system, annotations]
|
build_type: [backend, frontend, system, annotations]
|
||||||
target: [core, plugins, themes]
|
target: [core, plugins, themes]
|
||||||
ruby: ["3.2"]
|
ruby: ["3.2"]
|
||||||
updated_ember: [true]
|
|
||||||
exclude:
|
exclude:
|
||||||
- build_type: annotations
|
- build_type: annotations
|
||||||
target: plugins
|
target: plugins
|
||||||
|
@ -58,7 +56,6 @@ jobs:
|
||||||
include:
|
include:
|
||||||
- build_type: system
|
- build_type: system
|
||||||
target: chat
|
target: chat
|
||||||
updated_ember: true
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set working directory owner
|
- name: Set working directory owner
|
||||||
|
@ -299,7 +296,7 @@ jobs:
|
||||||
id: fetch-job-id
|
id: fetch-job-id
|
||||||
if: always() && steps.check-flaky-spec-report.outputs.exists == 'true'
|
if: always() && steps.check-flaky-spec-report.outputs.exists == 'true'
|
||||||
run: |
|
run: |
|
||||||
job_id=$(ruby script/get_github_workflow_run_job_id.rb ${{ github.run_id }} ${{ github.run_attempt }} '${{ matrix.target }} ${{ matrix.build_type }}${{ !matrix.updated_ember && ' (Ember 3)' || '' }}')
|
job_id=$(ruby script/get_github_workflow_run_job_id.rb ${{ github.run_id }} ${{ github.run_attempt }} '${{ matrix.target }} ${{ matrix.build_type }}')
|
||||||
echo "job_id=$job_id" >> $GITHUB_OUTPUT
|
echo "job_id=$job_id" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Create flaky tests report artifact
|
- name: Create flaky tests report artifact
|
||||||
|
@ -332,7 +329,7 @@ jobs:
|
||||||
|
|
||||||
core_frontend_tests:
|
core_frontend_tests:
|
||||||
if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
|
if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
|
||||||
name: core frontend (${{ matrix.browser }})${{ !matrix.updated_ember && ' (Ember 3)' || '' }}
|
name: core frontend (${{ matrix.browser }})
|
||||||
runs-on: ubuntu-20.04-8core
|
runs-on: ubuntu-20.04-8core
|
||||||
container:
|
container:
|
||||||
image: discourse/discourse_test:slim-browsers
|
image: discourse/discourse_test:slim-browsers
|
||||||
|
@ -344,10 +341,6 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
browser: ["Chrome", "Firefox ESR", "Firefox Evergreen"]
|
browser: ["Chrome", "Firefox ESR", "Firefox Evergreen"]
|
||||||
updated_ember: [true]
|
|
||||||
include:
|
|
||||||
- browser: Chrome
|
|
||||||
updated_ember: false
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
TESTEM_BROWSER: ${{ (startsWith(matrix.browser, 'Firefox') && 'Firefox') || matrix.browser }}
|
TESTEM_BROWSER: ${{ (startsWith(matrix.browser, 'Firefox') && 'Firefox') || matrix.browser }}
|
||||||
|
@ -374,10 +367,6 @@ jobs:
|
||||||
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-cachev2
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-cachev2
|
||||||
|
|
||||||
- name: Downgrade Ember
|
|
||||||
if: matrix.updated_ember == false
|
|
||||||
run: script/switch_ember_version 3
|
|
||||||
|
|
||||||
- name: Yarn install
|
- name: Yarn install
|
||||||
working-directory: ./app/assets/javascripts/discourse
|
working-directory: ./app/assets/javascripts/discourse
|
||||||
run: yarn install --frozen-lockfile
|
run: yarn install --frozen-lockfile
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
{{! Remove when legacy modals are dropped (deprecation: discourse.modal-controllers) }}
|
|
||||||
|
|
||||||
<div
|
|
||||||
id={{@id}}
|
|
||||||
class={{concat-class "modal-body" @class}}
|
|
||||||
tabindex="-1"
|
|
||||||
{{did-insert this.didInsert}}
|
|
||||||
{{will-destroy this.willDestroy}}
|
|
||||||
...attributes
|
|
||||||
>
|
|
||||||
{{yield}}
|
|
||||||
</div>
|
|
|
@ -1,72 +0,0 @@
|
||||||
// Remove when legacy modals are dropped (deprecation: discourse.modal-controllers)
|
|
||||||
|
|
||||||
import Component from "@glimmer/component";
|
|
||||||
import { DEBUG } from "@glimmer/env";
|
|
||||||
import { tracked } from "@glimmer/tracking";
|
|
||||||
import { action } from "@ember/object";
|
|
||||||
import { inject as service } from "@ember/service";
|
|
||||||
import $ from "jquery";
|
|
||||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
|
||||||
|
|
||||||
const LEGACY_ERROR =
|
|
||||||
"d-modal-body should only be used inside a legacy controller-based d-modal. https://meta.discourse.org/t/268057";
|
|
||||||
|
|
||||||
function pick(object, keys) {
|
|
||||||
const result = {};
|
|
||||||
for (const key of keys) {
|
|
||||||
if (key in object) {
|
|
||||||
result[key] = object[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@disableImplicitInjections
|
|
||||||
export default class DModalBody extends Component {
|
|
||||||
@service appEvents;
|
|
||||||
@service modal;
|
|
||||||
|
|
||||||
@tracked fixed = false;
|
|
||||||
|
|
||||||
@action
|
|
||||||
didInsert(element) {
|
|
||||||
if (element.closest(".d-modal:not(.d-modal-legacy)")) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(LEGACY_ERROR);
|
|
||||||
if (DEBUG) {
|
|
||||||
throw new Error(LEGACY_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.appEvents.trigger("modal-body:clearFlash");
|
|
||||||
|
|
||||||
const fixedParent = element.closest(".d-modal.fixed-modal");
|
|
||||||
if (fixedParent) {
|
|
||||||
this.fixed = true;
|
|
||||||
$(fixedParent).modal("show");
|
|
||||||
this.modal.hidden = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.appEvents.trigger(
|
|
||||||
"modal:body-shown",
|
|
||||||
pick(this.args, [
|
|
||||||
"title",
|
|
||||||
"rawTitle",
|
|
||||||
"fixed",
|
|
||||||
"subtitle",
|
|
||||||
"rawSubtitle",
|
|
||||||
"submitOnEnter",
|
|
||||||
"dismissable",
|
|
||||||
"headerClass",
|
|
||||||
"modalClass",
|
|
||||||
"titleAriaElementId",
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
willDestroy() {
|
|
||||||
super.willDestroy(...arguments);
|
|
||||||
this.appEvents.trigger("modal:body-dismissed");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
{{! Remove when legacy modals are dropped (deprecation: discourse.modal-controllers) }}
|
|
||||||
|
|
||||||
{{! template-lint-disable no-pointer-down-event-binding }}
|
|
||||||
{{! template-lint-disable no-invalid-interactive }}
|
|
||||||
|
|
||||||
<div
|
|
||||||
class={{concat-class
|
|
||||||
this.modalClass
|
|
||||||
this.modalStyle
|
|
||||||
(if this.hasPanels "has-panels")
|
|
||||||
(if @hidden "hidden")
|
|
||||||
"d-modal-legacy"
|
|
||||||
}}
|
|
||||||
id={{if (not-eq this.modalStyle "inline-modal") "discourse-modal"}}
|
|
||||||
data-keyboard="false"
|
|
||||||
aria-modal="true"
|
|
||||||
role="dialog"
|
|
||||||
aria-labelledby={{this.ariaLabelledby}}
|
|
||||||
...attributes
|
|
||||||
{{did-insert this.setupListeners}}
|
|
||||||
{{will-destroy this.cleanupListeners}}
|
|
||||||
{{on "mousedown" this.handleMouseDown}}
|
|
||||||
>
|
|
||||||
<div class="modal-outer-container">
|
|
||||||
<div class="modal-middle-container">
|
|
||||||
<div class="modal-inner-container">
|
|
||||||
<PluginOutlet @name="above-modal-header" @connectorTagName="div" />
|
|
||||||
<div class="modal-header {{this.headerClass}}">
|
|
||||||
{{#if this.dismissable}}
|
|
||||||
<DButton
|
|
||||||
@icon="times"
|
|
||||||
@action={{route-action "closeModal" "initiatedByCloseButton"}}
|
|
||||||
@title="modal.close"
|
|
||||||
class="btn-flat modal-close close"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="modal-title-wrapper">
|
|
||||||
{{#if this.title}}
|
|
||||||
<div class="title">
|
|
||||||
<h3 id="discourse-modal-title">{{this.title}}</h3>
|
|
||||||
|
|
||||||
{{#if this.subtitle}}
|
|
||||||
<p class="subtitle">{{this.subtitle}}</p>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<span id="modal-header-after-title"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if this.panels}}
|
|
||||||
<ul class="modal-tabs">
|
|
||||||
{{#each this.panels as |panel|}}
|
|
||||||
<ModalTab
|
|
||||||
@panel={{panel}}
|
|
||||||
@panelsLength={{this.panels.length}}
|
|
||||||
@selectedPanel={{@selectedPanel}}
|
|
||||||
@onSelectPanel={{@onSelectPanel}}
|
|
||||||
/>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
id="modal-alert"
|
|
||||||
role="alert"
|
|
||||||
class={{if
|
|
||||||
this.flash
|
|
||||||
(concat-class
|
|
||||||
"alert" (concat "alert-" (or this.flash.messageClass "success"))
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{{~this.flash.text~}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{outlet "modalBody"}}
|
|
||||||
|
|
||||||
{{#each this.errors as |error|}}
|
|
||||||
<div class="alert alert-error">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="close"
|
|
||||||
data-dismiss="alert"
|
|
||||||
aria-label={{i18n "modal.dismiss_error"}}
|
|
||||||
>×</button>
|
|
||||||
{{error}}
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,253 +0,0 @@
|
||||||
// Remove when legacy modals are dropped (deprecation: discourse.modal-controllers)
|
|
||||||
|
|
||||||
import Component from "@glimmer/component";
|
|
||||||
import { tracked } from "@glimmer/tracking";
|
|
||||||
import { action } from "@ember/object";
|
|
||||||
import { next, schedule } from "@ember/runloop";
|
|
||||||
import { inject as service } from "@ember/service";
|
|
||||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
|
||||||
import { bind } from "discourse-common/utils/decorators";
|
|
||||||
import I18n from "discourse-i18n";
|
|
||||||
|
|
||||||
@disableImplicitInjections
|
|
||||||
export default class DModal extends Component {
|
|
||||||
@service appEvents;
|
|
||||||
@service modal;
|
|
||||||
|
|
||||||
@tracked wrapperElement;
|
|
||||||
@tracked modalBodyData = {};
|
|
||||||
@tracked flash;
|
|
||||||
|
|
||||||
get modalStyle() {
|
|
||||||
if (this.args.modalStyle === "inline-modal") {
|
|
||||||
return "inline-modal";
|
|
||||||
} else {
|
|
||||||
return "fixed-modal";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get submitOnEnter() {
|
|
||||||
if ("submitOnEnter" in this.modalBodyData) {
|
|
||||||
return this.modalBodyData.submitOnEnter;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get dismissable() {
|
|
||||||
if ("dismissable" in this.modalBodyData) {
|
|
||||||
return this.modalBodyData.dismissable;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get title() {
|
|
||||||
if (this.modalBodyData.title) {
|
|
||||||
return I18n.t(this.modalBodyData.title);
|
|
||||||
} else if (this.modalBodyData.rawTitle) {
|
|
||||||
return this.modalBodyData.rawTitle;
|
|
||||||
} else {
|
|
||||||
return this.args.title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get subtitle() {
|
|
||||||
if (this.modalBodyData.subtitle) {
|
|
||||||
return I18n.t(this.modalBodyData.subtitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.modalBodyData.rawSubtitle || this.args.subtitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
get headerClass() {
|
|
||||||
return this.modalBodyData.headerClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
get panels() {
|
|
||||||
return this.args.panels;
|
|
||||||
}
|
|
||||||
|
|
||||||
get errors() {
|
|
||||||
return this.args.errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
setupListeners(element) {
|
|
||||||
this.appEvents.on("modal:body-shown", this._modalBodyShown);
|
|
||||||
this.appEvents.on("modal-body:flash", this._flash);
|
|
||||||
this.appEvents.on("modal-body:clearFlash", this._clearFlash);
|
|
||||||
document.documentElement.addEventListener(
|
|
||||||
"keydown",
|
|
||||||
this._handleModalEvents
|
|
||||||
);
|
|
||||||
this.wrapperElement = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
cleanupListeners() {
|
|
||||||
this.appEvents.off("modal:body-shown", this._modalBodyShown);
|
|
||||||
this.appEvents.off("modal-body:flash", this._flash);
|
|
||||||
this.appEvents.off("modal-body:clearFlash", this._clearFlash);
|
|
||||||
document.documentElement.removeEventListener(
|
|
||||||
"keydown",
|
|
||||||
this._handleModalEvents
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get ariaLabelledby() {
|
|
||||||
if (this.modalBodyData.titleAriaElementId) {
|
|
||||||
return this.modalBodyData.titleAriaElementId;
|
|
||||||
} else if (this.args.titleAriaElementId) {
|
|
||||||
return this.args.titleAriaElementId;
|
|
||||||
} else if (this.args.title) {
|
|
||||||
return "discourse-modal-title";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get modalClass() {
|
|
||||||
return this.modalBodyData.modalClass || this.args.modalClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerClickOnEnter(e) {
|
|
||||||
if (!this.submitOnEnter) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip when in a form or a textarea element
|
|
||||||
if (
|
|
||||||
e.target.closest("form") ||
|
|
||||||
(document.activeElement && document.activeElement.nodeName === "TEXTAREA")
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
handleMouseDown(e) {
|
|
||||||
if (!this.dismissable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
e.target.classList.contains("modal-middle-container") ||
|
|
||||||
e.target.classList.contains("modal-outer-container")
|
|
||||||
) {
|
|
||||||
// Send modal close (which bubbles to ApplicationRoute) if clicked outside.
|
|
||||||
// We do this because some CSS of ours seems to cover the backdrop and makes
|
|
||||||
// it unclickable.
|
|
||||||
return this.args.closeModal?.("initiatedByClickOut");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@bind
|
|
||||||
_modalBodyShown(data) {
|
|
||||||
if (this.isDestroying || this.isDestroyed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.fixed) {
|
|
||||||
this.modal.hidden = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.modalBodyData = data;
|
|
||||||
|
|
||||||
next(() => {
|
|
||||||
schedule("afterRender", () => {
|
|
||||||
this._trapTab();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@bind
|
|
||||||
_handleModalEvents(event) {
|
|
||||||
if (this.args.hidden) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === "Escape" && this.dismissable) {
|
|
||||||
next(() => this.args.closeModal("initiatedByESC"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === "Enter" && this.triggerClickOnEnter(event)) {
|
|
||||||
this.wrapperElement.querySelector(".modal-footer .btn-primary")?.click();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === "Tab") {
|
|
||||||
this._trapTab(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_trapTab(event) {
|
|
||||||
if (this.args.hidden) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const innerContainer = this.wrapperElement.querySelector(
|
|
||||||
".modal-inner-container"
|
|
||||||
);
|
|
||||||
if (!innerContainer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let focusableElements =
|
|
||||||
'[autofocus], a, input, select, textarea, summary, [tabindex]:not([tabindex="-1"])';
|
|
||||||
|
|
||||||
if (!event) {
|
|
||||||
// on first trap we don't allow to focus modal-close
|
|
||||||
// and apply manual focus only if we don't have any autofocus element
|
|
||||||
const autofocusedElement = innerContainer.querySelector("[autofocus]");
|
|
||||||
if (
|
|
||||||
!autofocusedElement ||
|
|
||||||
document.activeElement !== autofocusedElement
|
|
||||||
) {
|
|
||||||
// if there's not autofocus, or the activeElement, is not the autofocusable element
|
|
||||||
// attempt to focus the first of the focusable elements or just the modal-body
|
|
||||||
// to make it possible to scroll with arrow down/up
|
|
||||||
(
|
|
||||||
autofocusedElement ||
|
|
||||||
innerContainer.querySelector(
|
|
||||||
focusableElements + ", button:not(.modal-close)"
|
|
||||||
) ||
|
|
||||||
innerContainer.querySelector(".modal-body")
|
|
||||||
)?.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
focusableElements += ", button:enabled";
|
|
||||||
|
|
||||||
const firstFocusableElement =
|
|
||||||
innerContainer.querySelector(focusableElements);
|
|
||||||
const focusableContent = innerContainer.querySelectorAll(focusableElements);
|
|
||||||
const lastFocusableElement = focusableContent[focusableContent.length - 1];
|
|
||||||
|
|
||||||
if (event.shiftKey) {
|
|
||||||
if (document.activeElement === firstFocusableElement) {
|
|
||||||
lastFocusableElement?.focus();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (document.activeElement === lastFocusableElement) {
|
|
||||||
(
|
|
||||||
innerContainer.querySelector(".modal-close") || firstFocusableElement
|
|
||||||
)?.focus();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@bind
|
|
||||||
_clearFlash() {
|
|
||||||
this.flash = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@bind
|
|
||||||
_flash(msg) {
|
|
||||||
this.flash = msg;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,25 +10,3 @@
|
||||||
/>
|
/>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.renderLegacy}}
|
|
||||||
<DModalLegacy
|
|
||||||
@modalClass={{if
|
|
||||||
this.modal.isLegacy
|
|
||||||
(concat-class
|
|
||||||
"modal"
|
|
||||||
"d-modal"
|
|
||||||
this.modal.modalClass
|
|
||||||
(if this.modal.opts.panels "has-tabs")
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
@title={{this.modal.title}}
|
|
||||||
@titleAriaElementId={{this.modal.opts.titleAriaElementId}}
|
|
||||||
@panels={{this.modal.opts.panels}}
|
|
||||||
@selectedPanel={{this.modal.selectedPanel}}
|
|
||||||
@onSelectPanel={{this.modal.onSelectPanel}}
|
|
||||||
@hidden={{this.modal.hidden}}
|
|
||||||
@errors={{this.modal.errors}}
|
|
||||||
@closeModal={{this.closeModal}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
|
@ -1,7 +1,6 @@
|
||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import { EMBER_MAJOR_VERSION } from "discourse/lib/ember-version";
|
|
||||||
|
|
||||||
export default class ModalContainer extends Component {
|
export default class ModalContainer extends Component {
|
||||||
@service modal;
|
@service modal;
|
||||||
|
@ -10,8 +9,4 @@ export default class ModalContainer extends Component {
|
||||||
closeModal(data) {
|
closeModal(data) {
|
||||||
this.modal.close(data);
|
this.modal.close(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
get renderLegacy() {
|
|
||||||
return EMBER_MAJOR_VERSION < 4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import Component from "@ember/component";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import Ember from "ember";
|
import Ember from "ember";
|
||||||
import { actionModifier } from "./ember-action-modifier";
|
import { actionModifier } from "./ember-action-modifier";
|
||||||
import { EMBER_MAJOR_VERSION } from "./ember-version";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classic Ember components (i.e. "@ember/component") rely upon "event
|
* Classic Ember components (i.e. "@ember/component") rely upon "event
|
||||||
|
@ -127,16 +126,13 @@ function rewireClassicComponentEvents(app) {
|
||||||
allEventMethods[methodName] = event;
|
allEventMethods[methodName] = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
const triggerOverrideMethod =
|
|
||||||
EMBER_MAJOR_VERSION < 4 ? "trigger" : "_trigger";
|
|
||||||
|
|
||||||
// Avoid Component.reopen to stop `ember.component.reopen` deprecation warning
|
// Avoid Component.reopen to stop `ember.component.reopen` deprecation warning
|
||||||
EmberObject.reopen.call(Component, {
|
EmberObject.reopen.call(Component, {
|
||||||
/**
|
/**
|
||||||
* @param {string | typeof INTERNAL} name
|
* @param {string | typeof INTERNAL} name
|
||||||
* @param {unknown[]} args
|
* @param {unknown[]} args
|
||||||
*/
|
*/
|
||||||
[triggerOverrideMethod](name, ...args) {
|
_trigger(name, ...args) {
|
||||||
if (name === INTERNAL) {
|
if (name === INTERNAL) {
|
||||||
if (this.element) {
|
if (this.element) {
|
||||||
return this._super.call(this, ...args);
|
return this._super.call(this, ...args);
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
import { tracked } from "@glimmer/tracking";
|
import { tracked } from "@glimmer/tracking";
|
||||||
import { getOwner } from "@ember/application";
|
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import Service, { inject as service } from "@ember/service";
|
import Service, { inject as service } from "@ember/service";
|
||||||
import { dasherize } from "@ember/string";
|
|
||||||
import $ from "jquery";
|
|
||||||
import { CLOSE_INITIATED_BY_MODAL_SHOW } from "discourse/components/d-modal";
|
import { CLOSE_INITIATED_BY_MODAL_SHOW } from "discourse/components/d-modal";
|
||||||
import { EMBER_MAJOR_VERSION } from "discourse/lib/ember-version";
|
|
||||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||||
import deprecated, {
|
import deprecated from "discourse-common/lib/deprecated";
|
||||||
withSilencedDeprecations,
|
|
||||||
} from "discourse-common/lib/deprecated";
|
|
||||||
import I18n from "discourse-i18n";
|
|
||||||
|
|
||||||
const LEGACY_OPTS = new Set([
|
const LEGACY_OPTS = new Set([
|
||||||
"admin",
|
"admin",
|
||||||
|
@ -23,7 +16,7 @@ const LEGACY_OPTS = new Set([
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@disableImplicitInjections
|
@disableImplicitInjections
|
||||||
class ModalService extends Service {
|
export default class ModalService extends Service {
|
||||||
@service dialog;
|
@service dialog;
|
||||||
|
|
||||||
@tracked activeModal;
|
@tracked activeModal;
|
||||||
|
@ -93,195 +86,3 @@ class ModalService extends Service {
|
||||||
this.opts = {};
|
this.opts = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all logic below when legacy modals are dropped (deprecation: discourse.modal-controllers)
|
|
||||||
class ModalServiceWithLegacySupport extends ModalService {
|
|
||||||
@service appEvents;
|
|
||||||
|
|
||||||
@tracked name;
|
|
||||||
@tracked selectedPanel;
|
|
||||||
@tracked hidden = true;
|
|
||||||
|
|
||||||
@tracked titleOverride;
|
|
||||||
@tracked modalClassOverride;
|
|
||||||
@tracked onSelectPanel;
|
|
||||||
|
|
||||||
get title() {
|
|
||||||
if (this.titleOverride) {
|
|
||||||
return this.titleOverride;
|
|
||||||
} else if (this.opts.titleTranslated) {
|
|
||||||
return this.opts.titleTranslated;
|
|
||||||
} else if (this.opts.title) {
|
|
||||||
return I18n.t(this.opts.title);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set title(value) {
|
|
||||||
this.titleOverride = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get modalClass() {
|
|
||||||
if (!this.isLegacy) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
this.modalClassOverride ||
|
|
||||||
this.opts.modalClass ||
|
|
||||||
`${dasherize(this.name.replace(/^modals\//, "")).toLowerCase()}-modal`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
set modalClass(value) {
|
|
||||||
this.modalClassOverride = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
show(modal, opts = {}) {
|
|
||||||
if (typeof modal !== "string") {
|
|
||||||
return super.show(modal, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.close({ initiatedBy: CLOSE_INITIATED_BY_MODAL_SHOW });
|
|
||||||
|
|
||||||
deprecated(
|
|
||||||
`Defining modals using a controller is deprecated. Use the component-based API instead. (modal: ${modal})`,
|
|
||||||
{
|
|
||||||
id: "discourse.modal-controllers",
|
|
||||||
since: "3.1",
|
|
||||||
dropFrom: "3.2",
|
|
||||||
url: "https://meta.discourse.org/t/268057",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const name = modal;
|
|
||||||
const container = getOwner(this);
|
|
||||||
const route = container.lookup("route:application");
|
|
||||||
|
|
||||||
this.opts = opts;
|
|
||||||
|
|
||||||
const controllerName = opts.admin ? `modals/${name}` : name;
|
|
||||||
this.name = controllerName;
|
|
||||||
|
|
||||||
let controller = container.lookup("controller:" + controllerName);
|
|
||||||
const templateName = opts.templateName || dasherize(name);
|
|
||||||
|
|
||||||
const renderArgs = { into: "application", outlet: "modalBody" };
|
|
||||||
if (controller) {
|
|
||||||
renderArgs.controller = controllerName;
|
|
||||||
} else {
|
|
||||||
// use a basic controller
|
|
||||||
renderArgs.controller = "basic-modal-body";
|
|
||||||
controller = container.lookup(`controller:${renderArgs.controller}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.addModalBodyView) {
|
|
||||||
renderArgs.view = "modal-body";
|
|
||||||
}
|
|
||||||
|
|
||||||
const modalName = `modal/${templateName}`;
|
|
||||||
const fullName = opts.admin ? `admin/templates/${modalName}` : modalName;
|
|
||||||
|
|
||||||
// Any use of the legacy modal system will trigger Discourse's own deprecation message
|
|
||||||
// so we can silence Ember's message here.
|
|
||||||
withSilencedDeprecations("route-render-template", () => {
|
|
||||||
route.render(fullName, renderArgs);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (opts.panels) {
|
|
||||||
if (controller.actions.onSelectPanel) {
|
|
||||||
this.onSelectPanel = controller.actions.onSelectPanel.bind(controller);
|
|
||||||
}
|
|
||||||
this.selectedPanel = opts.panels[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.set("modal", this);
|
|
||||||
const model = opts.model;
|
|
||||||
if (model) {
|
|
||||||
controller.set("model", model);
|
|
||||||
}
|
|
||||||
if (controller.onShow) {
|
|
||||||
controller.onShow();
|
|
||||||
}
|
|
||||||
controller.set("flashMessage", null);
|
|
||||||
|
|
||||||
return (this.activeController = controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(initiatedBy) {
|
|
||||||
if (!this.isLegacy) {
|
|
||||||
super.close(...arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
const controllerName = this.name;
|
|
||||||
const controller = controllerName
|
|
||||||
? getOwner(this).lookup(`controller:${controllerName}`)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (controller?.beforeClose?.() === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const applicationRoute = getOwner(this).lookup("route:application");
|
|
||||||
|
|
||||||
// Any use of the legacy modal system will trigger Discourse's own deprecation message
|
|
||||||
// so we can silence Ember's message here.
|
|
||||||
withSilencedDeprecations("route-render-template", () => {
|
|
||||||
applicationRoute.render("hide-modal", {
|
|
||||||
into: "application",
|
|
||||||
outlet: "modalBody",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$(".d-modal.fixed-modal").modal("hide");
|
|
||||||
|
|
||||||
if (controller) {
|
|
||||||
this.appEvents.trigger("modal:closed", {
|
|
||||||
name: controllerName,
|
|
||||||
controller,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (controller.onClose) {
|
|
||||||
controller.onClose({
|
|
||||||
initiatedByCloseButton: initiatedBy === "initiatedByCloseButton",
|
|
||||||
initiatedByClickOut: initiatedBy === "initiatedByClickOut",
|
|
||||||
initiatedByESC: initiatedBy === "initiatedByESC",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.hidden = true;
|
|
||||||
|
|
||||||
this.name =
|
|
||||||
this.selectedPanel =
|
|
||||||
this.modalClassOverride =
|
|
||||||
this.titleOverride =
|
|
||||||
this.onSelectPanel =
|
|
||||||
null;
|
|
||||||
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
if (this.isLegacy) {
|
|
||||||
$(".d-modal.fixed-modal").modal("hide");
|
|
||||||
} else {
|
|
||||||
throw "hide/reopen are not supported for component-based modals";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reopen() {
|
|
||||||
if (this.isLegacy) {
|
|
||||||
$(".d-modal.fixed-modal").modal("show");
|
|
||||||
} else {
|
|
||||||
throw "hide/reopen are not supported for component-based modals";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get isLegacy() {
|
|
||||||
return this.name && !this.activeModal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EMBER_MAJOR_VERSION >= 4
|
|
||||||
? ModalService
|
|
||||||
: ModalServiceWithLegacySupport;
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
const EMBER_MAJOR_VERSION = parseInt(
|
|
||||||
require("ember-source/package.json").version.split(".")[0],
|
|
||||||
10
|
|
||||||
);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"application-template-wrapper": false,
|
"application-template-wrapper": false,
|
||||||
"default-async-observers": true,
|
"default-async-observers": true,
|
||||||
"jquery-integration": EMBER_MAJOR_VERSION < 4,
|
"jquery-integration": false,
|
||||||
"template-only-glimmer-components": true,
|
"template-only-glimmer-components": true,
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,25 +18,8 @@ const withSideWatch = require("./lib/with-side-watch");
|
||||||
const RawHandlebarsCompiler = require("discourse-hbr/raw-handlebars-compiler");
|
const RawHandlebarsCompiler = require("discourse-hbr/raw-handlebars-compiler");
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
|
|
||||||
const EMBER_MAJOR_VERSION = parseInt(
|
|
||||||
require("ember-source/package.json").version.split(".")[0],
|
|
||||||
10
|
|
||||||
);
|
|
||||||
|
|
||||||
process.env.BROCCOLI_ENABLED_MEMOIZE = true;
|
process.env.BROCCOLI_ENABLED_MEMOIZE = true;
|
||||||
|
|
||||||
function filterForEmberVersion(tree) {
|
|
||||||
if (EMBER_MAJOR_VERSION < 4) {
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
return funnel(tree, {
|
|
||||||
// d-modal-legacy includes a named outlet which would cause
|
|
||||||
// a build failure in modern Ember
|
|
||||||
exclude: ["**/components/d-modal-legacy.hbs"],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function (defaults) {
|
module.exports = function (defaults) {
|
||||||
const discourseRoot = path.resolve("../../../..");
|
const discourseRoot = path.resolve("../../../..");
|
||||||
const vendorJs = discourseRoot + "/vendor/assets/javascripts/";
|
const vendorJs = discourseRoot + "/vendor/assets/javascripts/";
|
||||||
|
@ -92,21 +75,12 @@ module.exports = function (defaults) {
|
||||||
},
|
},
|
||||||
|
|
||||||
trees: {
|
trees: {
|
||||||
app: filterForEmberVersion(
|
app: RawHandlebarsCompiler(
|
||||||
RawHandlebarsCompiler(
|
|
||||||
withSideWatch("app", { watching: ["../discourse-markdown-it"] })
|
withSideWatch("app", { watching: ["../discourse-markdown-it"] })
|
||||||
)
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (EMBER_MAJOR_VERSION < 4) {
|
|
||||||
// TODO: remove me
|
|
||||||
// Ember 3.28 still has some internal dependency on jQuery being a global,
|
|
||||||
// for the time being we will bring it in vendor.js
|
|
||||||
app.import("node_modules/jquery/dist/jquery.js", { prepend: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// WARNING: We should only import scripts here if they are not in NPM.
|
// WARNING: We should only import scripts here if they are not in NPM.
|
||||||
app.import(vendorJs + "bootbox.js");
|
app.import(vendorJs + "bootbox.js");
|
||||||
app.import(discourseRoot + "/app/assets/javascripts/polyfills.js");
|
app.import(discourseRoot + "/app/assets/javascripts/polyfills.js");
|
||||||
|
@ -186,8 +160,7 @@ module.exports = function (defaults) {
|
||||||
if (
|
if (
|
||||||
!request.includes("-embroider-implicit") &&
|
!request.includes("-embroider-implicit") &&
|
||||||
// TODO: delete special case for jquery when removing app.import() above
|
// TODO: delete special case for jquery when removing app.import() above
|
||||||
((EMBER_MAJOR_VERSION < 4 && request === "jquery") ||
|
(request.startsWith("admin/") ||
|
||||||
request.startsWith("admin/") ||
|
|
||||||
request.startsWith("discourse/plugins/") ||
|
request.startsWith("discourse/plugins/") ||
|
||||||
request.startsWith("discourse/theme-"))
|
request.startsWith("discourse/theme-"))
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -26,30 +26,3 @@ define("ember-addons/ember-computed-decorators", [
|
||||||
);
|
);
|
||||||
return decorators;
|
return decorators;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Based on https://github.com/emberjs/ember-jquery-legacy
|
|
||||||
// The addon has out-of-date dependences, but it's super simple so we can reproduce here instead:
|
|
||||||
define("ember-jquery-legacy", ["exports"], function (exports) {
|
|
||||||
exports.normalizeEvent = function (e) {
|
|
||||||
if (e instanceof Event) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
// __originalEvent is a private escape hatch of Ember's EventDispatcher to allow accessing `originalEvent` without
|
|
||||||
// triggering a deprecation message.
|
|
||||||
return e.__originalEvent || e.originalEvent;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// ember-cached-decorator-polyfill uses a Babel transformation to apply this polyfill in core.
|
|
||||||
// Adding that Babel transformation to themes and plugins will be complex, so we use this to
|
|
||||||
// patch it at runtime. This can be removed once `@glimmer/tracking` is updated to a version
|
|
||||||
// with native `@cached` support.
|
|
||||||
const glimmerTracking = require("@glimmer/tracking");
|
|
||||||
if (glimmerTracking.cached) {
|
|
||||||
// No-op. Can be removed once we're fully upgraded to Ember 4+
|
|
||||||
// Search juice: EMBER_MAJOR_VERSION < 4;
|
|
||||||
} else {
|
|
||||||
Object.defineProperty(glimmerTracking, "cached", {
|
|
||||||
get: () => require("ember-cached-decorator-polyfill").cached,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
{
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"postinstall": "./run-patch-package"
|
|
||||||
},
|
|
||||||
"workspaces": [
|
|
||||||
"admin",
|
|
||||||
"bootstrap-json",
|
|
||||||
"deprecation-silencer",
|
|
||||||
"dialog-holder",
|
|
||||||
"discourse",
|
|
||||||
"discourse-common",
|
|
||||||
"discourse-hbr",
|
|
||||||
"discourse-i18n",
|
|
||||||
"discourse-markdown-it",
|
|
||||||
"discourse-plugins",
|
|
||||||
"discourse-widget-hbs",
|
|
||||||
"ember-cli-progress-ci",
|
|
||||||
"ember-production-deprecations",
|
|
||||||
"float-kit",
|
|
||||||
"pretty-text",
|
|
||||||
"select-kit",
|
|
||||||
"theme-transpiler",
|
|
||||||
"truth-helpers"
|
|
||||||
],
|
|
||||||
"resolutions": {
|
|
||||||
"**/unset-value": "2.0.1",
|
|
||||||
"**/ember-source": "3.28.12"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"patch-package": "^8.0.0",
|
|
||||||
"postinstall-postinstall": "^2.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package-ember5.json
|
|
1
app/assets/javascripts/package.json
Normal file
1
app/assets/javascripts/package.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package-ember5.json
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
||||||
yarn-ember5.lock
|
|
1
app/assets/javascripts/yarn.lock
Normal file
1
app/assets/javascripts/yarn.lock
Normal file
|
@ -0,0 +1 @@
|
||||||
|
yarn-ember5.lock
|
|
@ -157,8 +157,7 @@ class AdminDashboardData
|
||||||
:unreachable_themes,
|
:unreachable_themes,
|
||||||
:watched_words_check,
|
:watched_words_check,
|
||||||
:google_analytics_version_check,
|
:google_analytics_version_check,
|
||||||
:translation_overrides_check,
|
:translation_overrides_check
|
||||||
:ember_version_check
|
|
||||||
|
|
||||||
add_problem_check { sidekiq_check || queue_size_check }
|
add_problem_check { sidekiq_check || queue_size_check }
|
||||||
end
|
end
|
||||||
|
@ -382,10 +381,6 @@ class AdminDashboardData
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def ember_version_check
|
|
||||||
I18n.t("dashboard.ember_version_warning") if ENV["EMBER_VERSION"] == "3"
|
|
||||||
end
|
|
||||||
|
|
||||||
def out_of_date_themes
|
def out_of_date_themes
|
||||||
old_themes = RemoteTheme.out_of_date_themes
|
old_themes = RemoteTheme.out_of_date_themes
|
||||||
return unless old_themes.present?
|
return unless old_themes.present?
|
||||||
|
|
|
@ -56,17 +56,6 @@ if !args.include?("test") && !args.include?("build") && !args.include?("--proxy"
|
||||||
args << PROXY
|
args << PROXY
|
||||||
end
|
end
|
||||||
|
|
||||||
if !["3", "5", nil].include?(ENV["EMBER_VERSION"])
|
|
||||||
raise "Unknown ember version #{ENV["EMBER_VERSION"]}"
|
|
||||||
end
|
|
||||||
|
|
||||||
system(
|
|
||||||
"script/switch_ember_version",
|
|
||||||
ENV["EMBER_VERSION"] || "5",
|
|
||||||
exception: true,
|
|
||||||
chdir: RAILS_ROOT,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Running yarn install in the root directory will also run it for YARN_DIR via a post-install hook
|
# Running yarn install in the root directory will also run it for YARN_DIR via a post-install hook
|
||||||
exit 1 if !system "yarn", "-s", "install", "--cwd", RAILS_ROOT
|
exit 1 if !system "yarn", "-s", "install", "--cwd", RAILS_ROOT
|
||||||
|
|
||||||
|
|
|
@ -1537,7 +1537,6 @@ en:
|
||||||
watched_word_regexp_error: "The regular expression for '%{action}' watched words is invalid. Please check your <a href='%{base_path}/admin/customize/watched_words'>Watched Word settings</a>, or disable the 'watched words regular expressions' site setting."
|
watched_word_regexp_error: "The regular expression for '%{action}' watched words is invalid. Please check your <a href='%{base_path}/admin/customize/watched_words'>Watched Word settings</a>, or disable the 'watched words regular expressions' site setting."
|
||||||
v3_analytics_deprecated: "Your Discourse is currently using Google Analytics 3, which will no longer be supported after July 2023. <a href='https://meta.discourse.org/t/260498'>Upgrade to Google Analytics 4</a> now to continue receiving valuable insights and analytics for your website's performance."
|
v3_analytics_deprecated: "Your Discourse is currently using Google Analytics 3, which will no longer be supported after July 2023. <a href='https://meta.discourse.org/t/260498'>Upgrade to Google Analytics 4</a> now to continue receiving valuable insights and analytics for your website's performance."
|
||||||
category_style_deprecated: "Your Discourse is currently using a deprecated category style which will be removed before the final beta release of Discourse 3.2. Please refer to <a href='https://meta.discourse.org/t/282441'>Moving to a Single Category Style Site Setting</a> for instructions on how to keep your selected category style."
|
category_style_deprecated: "Your Discourse is currently using a deprecated category style which will be removed before the final beta release of Discourse 3.2. Please refer to <a href='https://meta.discourse.org/t/282441'>Moving to a Single Category Style Site Setting</a> for instructions on how to keep your selected category style."
|
||||||
ember_version_warning: "Your site is running with the unsupported EMBER_VERSION=3 configuration. This may lead to unexpected issues with themes/plugins. Please remove the EMBER_VERSION configuration from your app.yml file and rebuild. See <a href='https://meta.discourse.org/t/287211'>https://meta.discourse.org/t/287211</a> for more information."
|
|
||||||
back_from_logster_text: "Back to site"
|
back_from_logster_text: "Back to site"
|
||||||
|
|
||||||
site_settings:
|
site_settings:
|
||||||
|
|
|
@ -10,13 +10,7 @@ task "assets:precompile:build" do
|
||||||
if ENV["SKIP_EMBER_CLI_COMPILE"] != "1"
|
if ENV["SKIP_EMBER_CLI_COMPILE"] != "1"
|
||||||
ember_version = ENV["EMBER_VERSION"] || "5"
|
ember_version = ENV["EMBER_VERSION"] || "5"
|
||||||
|
|
||||||
raise "Unknown ember version '#{ember_version}'" if !%w[3 5].include?(ember_version)
|
raise "Unknown ember version '#{ember_version}'" if !%w[5].include?(ember_version)
|
||||||
|
|
||||||
if ember_version == "3"
|
|
||||||
puts "Downgrading to Ember 3..."
|
|
||||||
system("script/switch_ember_version", ember_version, exception: true, chdir: Rails.root)
|
|
||||||
system("yarn install", exception: true, chdir: "app/assets/javascripts/discourse")
|
|
||||||
end
|
|
||||||
|
|
||||||
compile_command = "CI=1 yarn --cwd app/assets/javascripts/discourse run ember build"
|
compile_command = "CI=1 yarn --cwd app/assets/javascripts/discourse run ember build"
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "fileutils"
|
|
||||||
|
|
||||||
# rubocop:disable Discourse/NoChdir
|
|
||||||
Dir.chdir("#{__dir__}/../app/assets/javascripts") do
|
|
||||||
FileUtils.rm("yarn-ember3.lock")
|
|
||||||
FileUtils.cp("yarn-ember5.lock", "yarn-ember3.lock")
|
|
||||||
|
|
||||||
system("#{__dir__}/switch_ember_version", "3", exception: true)
|
|
||||||
|
|
||||||
system "yarn install", exception: true
|
|
||||||
|
|
||||||
system("#{__dir__}/switch_ember_version", "5", exception: true)
|
|
||||||
end
|
|
|
@ -1,17 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "fileutils"
|
|
||||||
|
|
||||||
v = ARGV[0]
|
|
||||||
|
|
||||||
raise "Unexpected version #{v}" if !%w[3 5].include?(v)
|
|
||||||
|
|
||||||
# rubocop:disable Discourse/NoChdir
|
|
||||||
Dir.chdir("#{__dir__}/../app/assets/javascripts") do
|
|
||||||
FileUtils.rm("package.json")
|
|
||||||
FileUtils.rm("yarn.lock")
|
|
||||||
|
|
||||||
File.symlink("package-ember#{v}.json", "package.json")
|
|
||||||
File.symlink("yarn-ember#{v}.lock", "yarn.lock")
|
|
||||||
end
|
|
Loading…
Reference in New Issue
Block a user