This adds a new `loaderShim()` function to ensure certain modules
are present in the `loader.js` registry and therefore runtime
`require()`-able.
Currently, the classic build pipeline puts a lot of things in the
runtime `loader.js` registry automatically. For example, all of
the ember-auto-import packages are in there.
Going forward, and especially as we switch to the Embroider build
pipeline, this will not be guarenteed. We need to keep an eye on
what modules (packages) our "external" bundles (admin, wizard,
markdown-it, plugins, etc) are expecting to be present and put
them into the registry proactively.
The gjs/gts formats are a new pattern for authoring Ember components. This commit introduces support for these patterns to our build pipeline for core/plugins, and converts a handful of components to use the new format. It also introduces relevant updates to our linting config, and to our sample vscode configuration.
Co-authored-by: Godfrey Chan <godfreykfc@gmail.com>
Co-authored-by: Krystan HuffMenne <kmenne+github@gmail.com>
Since 0fa92529ed, helpers can now be implemented as plain JS functions. This makes them much easier to write/read, and also makes them usable in `<template>` gjs files.
The primary motivation is to simplify `eagerLoadRawTemplateModules` which curently introspects the module dependencies (the `imports` at runtime). This is no longer supported in Embroider as the AMD shims do not have any dependencies (since it's managed internally with webpack).
These avatar-related helper functions are used in pretty-text, which currently means we load the entire `discourse/lib/utilities` module into the mini-racer when running pretty-text on the server side. This stops us adding any logic or imports to discourse/lib/utilities which may depend on other `discourse/` namespace features.
This commit moves the avatar-related utils into a dedicated module in the `discourse-common` namespace, adds backwards-compatibility shims, and updates the pretty-text config accordingly.
This allows us to use `getOwner(this)` on widgets (without needing to resort to our custom `discourse-common/lib/get-owner` implementation which has a hacky fallback)
Watched words were converted to regular expressions containing \W, which
handled only ASCII characters. Using [^[:word]] instead ensures that
UTF-8 characters are also handled correctly.
Named outlets are deprecated and will be removed in Ember 4.x.
Backwards-compatibility shims are introduced so that plugin overrides to `controller:composer` are ported to `service:composer`.
It's important to keep our core log output as clean as possible to avoid 'crying wolf', and so that any deprecations triggered by plugin/theme tests are indeed caused by that theme/plugin, and not core.
This commit will make the core test suite fail if any deprecations are triggered. If a new deprecation is introduced (e.g. as part of a dependency update) and we need more time to resolve it it can be silenced via ember-deprecation-workflow.
This does not affect plugin/theme test runs.
The implementation previously generated a descriptor with an `initializer()`, and bound the function to the `this` context of the initializer. In native class syntax, the initializer of a descriptor is only called once, with a `this` context of the constructor, not the instance.
This commit updates the implementation so that it generates the bound function on-demand using a getter. This is the same strategy employed by ember's built-in `@action` decorator.
Unfortunately, this use of a getter means that the `@observes` decorator does not support being directly chained to `@debounce`. It throws the error "`observer must be provided a function or an observer definition`". The workaround is to put the observer on its own function, which then calls the debounced function. Given that we're aiming to reduce our usage of `@observes`, we've accepted the need for this workaround rather than spending the time to patch the implementation of `@observes`.
When user is watching category or tag (watching or watching first post) notifications are moved to other tab.
To achieve that and distinguish between post create to directly watched topics and indirectly watched topics, new notification type called `watching_category_or_tag` was introduced.
In the past, the result of template compilation would be stored directly in `Ember.TEMPLATES`. Following the move to more modern ember-cli-based compilation, templates are now compiled to es6 modules. To handle forward/backwards compatibility during these changes we had logic in `discourse-boot` which would extract templates from the es6 modules and store them into the legacy-style `Ember.TEMPLATES` object.
This commit removes that shim, and updates our resolver to fetch templates directly from es6 modules. This is closer to how 'vanilla' Ember handles template resolution. We still have a lot of discourse-specific logic, but now it is centralised in one location and should be easier to understand and normalize in future.
This commit should not introduce any behaviour change.
Previously we were trying to handle both async and sync use cases in a single function, but it was confusing to read and led to subtle race conditions. This commit separates the async version into a separate function.
- Count deprecations and print them to the console following QUnit runs
- In GitHub actions, write the same information as a job summary
- Add documentation to `discourse-common/lib/deprecated`
- Introduce `id` and `url` options to `deprecated`
- Introduce `withSilencedDeprecations` helper to allow testing deprecated code paths without making noise in the logs
This was previously reverted in 47035693b7.
This reverts commit 8c48285145. This introduced a bug which could cause sites to break when certain deprecations are hit. We'll re-introduce a fixed version of this change in a future commit.
- Count deprecations and print them to the console following QUnit runs
- In GitHub actions, write the same information as a job summary
- Add documentation to `discourse-common/lib/deprecated`
- Introduce `id` and `url` options to `deprecated`
- Introduce `withSilencedDeprecations` helper to allow testing deprecated code paths without making noise in the logs
This implementation attempts to be more resilient to background tab.
Notes:
- adds support for immediate arg in @debounce decorators
- fixes a bug in discourseDebounce which was not supporting immediate arg in tests
- chat-audio-manager has no tests as audio requires real user interaction and is hard to test reliably
Ember's default resolver only looks for components/services/etc. which are namespaced under the app's `modulePrefix` (`discourse`, in our case). To use addon components/services/etc., the addon must re-export them in its `app/` directory.
In order to support plugins, our custom resolver does a 'suffix match'. This has an unintended side-effect of matching things which are not part of the discourse app or themes/plugins. We've come to rely on this for a few in-repo addons like `select-kit`, `admin` and `wizard`.
This unrestricted 'suffix matching' can cause some very unexpected behaviour. For example, the ember-inspector browser extension has a module called `ember_debug/service/session`. When looking up `service:session`, our resolver was choosing that third-party service over our own Session service. This means Discourse fails to boot when the Ember Inspector is open.
This commit restricts the 'suffix matching' to a known set of namespaces. This brings us one step closer to the default Ember Resolver implementation, and reduces the chance of unexpected behaviour like the ember-inspector issue.
This commit also updates the `dialog-holder` addon to export its service under the app directory, so that we don't need to account for it in the resolver. We may want to consider doing the same for things like `select-kit` and `truth-helpers`, but is beyond the scope of this commit.
This PR changes the icon for `posted` notification types (these are the notifications that you receive when someone posts in a topic you're watching) from `reply` to `discourse-bell-exclamation`. We're doing this to visually distinguish between the `posted` notifications and `replied` notifications which are the notifications that you receive when someone replies to you directly.
Internal topic: t72835.
Previously we were relying on a highly-customized version of the unmaintained Barber gem for theme template compilation. This commit switches us to use our own DiscourseJsProcessor, which makes use of more modern patterns and will be easier to maintain going forward.
In summary:
- Refactors DiscourseJsProcessor to move multiline JS heredocs into a companion `discourse-js-processor.js` file
- Use MiniRacer's `.call` method to avoid manually escaping JS strings
- Move Theme template AST transformers into DiscourseJsProcessor, and formalise interface for extending RawHandlebars AST transformations
- Update Ember template compilation to use a babel-based approach, just like Ember CLI. This gives each template its own ES6 module rather than directly assigning `Ember.TEMPLATES` values
- Improve testing of template compilation (and move some tests from `theme_javascript_compiler_spec.rb` to `discourse_js_processor_spec.rb`
These are in widespread use, and upgrading themes/plugins right now would break their compatibility with the stable branch. These should be unsilenced for the release of 2.9.0 stable.
This will allow consumers to inject it using `topicTrackingState: service()` in preparation for the removal of implicit injections in Ember 4.0. `topic-tracking-state:main` is still available and will print a deprecation notice.
Ideally we would convert topic-tracking-state into a true service, rather than registering a model instance into the registry. However, inter-dependencies between service injections make this very difficult to achieve. We don't want to block Glimmer Component work, so this commit does the minimum for now.
This will allow consumers to inject it using `site: service()` in preparation for the removal of implicit injections in Ember 4.0. `site:main` is still available and will print a deprecation notice.
This will allow consumers to inject it using `session: service()` in preparation for the removal of implicit injections in Ember 4.0. `session:main` is still available and will print a deprecation notice.
This will allow consumers to inject it using `currentUser: service()` in preparation for the removal of implicit injections in Ember 4.0. `current-user:main` is still available and will print a deprecation notice.
Having them all in one place is much easier to reason with. It also means we can handle them without needing 'fake' registrations (which can sometimes cause odd behavior). This commit just moves the deprecation logic - it does not introduce any new deprecations.
* FEATURE: Add case-sensitivity flag to watched_words
Currently, all watched words are matched case-insensitively. This flag
allows a watched word to be flagged for case-sensitive matching.
To allow allow for backwards compatibility the flag is set to false by
default.
* FEATURE: Support case-sensitive creation of Watched Words via API
Extend admin creation and upload of Watched Words to support case
sensitive flag. This lays the ground work for supporting
case-insensitive matching of Watched Words.
Support for an extra column has also been introduced for the Watched
Words upload CSV file. The new column structure is as follows:
word,replacement,case_sentive
* FEATURE: Enable case-sensitive matching of Watched Words
WordWatcher's word_matcher_regexp now returns a list of regular
expressions instead of one case-insensitive regular expression.
With the ability to flag a Watched Word as case-sensitive, an action
can have words of both sensitivities.This makes the use of the global
Regexp::IGNORECASE flag added to all words problematic.
To get around platform limitations around the use of subexpression level
switches/flags, a list of regular expressions is returned instead, one for each
case sensitivity.
Word matching has also been updated to use this list of regular expressions
instead of one.
* FEATURE: Use case-sensitive regular expressions for Watched Words
Update Watched Words regular expressions matching and processing to handle
the extra metadata which comes along with the introduction of
case-sensitive Watched Words.
This allows case-sensitive Watched Words to matched as such.
* DEV: Simplify type casting of case-sensitive flag from uploads
Use builtin semantics instead of a custom method for converting
string case flags in uploaded Watched Words to boolean.
* UX: Add case-sensitivity details to Admin Watched Words UI
Update Watched Word form to include a toggle for case-sensitivity.
This also adds support for, case-sensitive testing and matching of Watched Word
in the admin UI.
* DEV: Code improvements from review feedback
- Extract watched word regex creation out to a utility function
- Make JS array presence check more explicit and readable
* DEV: Extract Watched Word regex creation to utility function
Clean-up work from review feedback. Reduce code duplication.
* DEV: Rename word_matcher_regexp to word_matcher_regexp_list
Since a list is returned now instead of a single regular expression,
change `word_matcher_regexp` to `word_matcher_regexp_list` to better communicate
this change.
* DEV: Incorporate WordWatcher updates from upstream
Resolve conflicts and ensure apply_to_text does not remove non-word characters in matches
that aren't at the beginning of the line.
Previously, if a non-admin controller did not have a template defined, then the resolver would return an admin template with the same name. This is not the desired behavior, and regressed in fc36ac6cde. However, we *do* want this behavior for components defined in the admin bundle (because admin components are not namespaced).
This was noticed because the non-admin `badges` route was using the `admin/badges` template
This commit fixes the behavior, and adds a tests for these cases.
Also, the change in insert-hyperlink (from `this.linkUrl.indexOf("http") === -1` to `!this.linkUrl.startsWith("http")`) was intentional fix: we don't want to prevent users from looking up topics with http in their titles.