Commit Graph

148 Commits

Author SHA1 Message Date
Dan Gebhardt
952b033165
FIX: Ensure that custom {{action}} modifier works with actions hash (#18779)
A callback that's provided as a string, such as `{{action "doSomething"}}`, may target the method `doSomething` on the context OR the context's `action` hash (if it exists).
2022-10-27 20:12:34 +01:00
Dan Gebhardt
0221855ba7
DEV: Normalize event handling to improve Glimmer + Classic component compat (Take 2) (#18742)
Classic Ember components (i.e. "@ember/component") rely upon "event
delegation" to listen for events at the application root and then dispatch
those events to any event handlers defined on individual Classic components.
This coordination is handled by Ember's EventDispatcher.

In contrast, Glimmer components (i.e. "@glimmer/component") expect event
listeners to be added to elements using modifiers (such as `{{on "click"}}`).
These event listeners are added directly to DOM elements using
`addEventListener`. There is no need for an event dispatcher.

Issues may arise when using Classic and Glimmer components together, since it
requires reconciling the two event handling approaches. For instance, event
propagation may not work as expected when a Classic component is nested
inside a Glimmer component.

`normalizeEmberEventHandling` helps an application standardize upon the
Glimmer event handling approach by eliminating usage of event delegation and
instead rewiring Classic components to directly use `addEventListener`.

Specifically, it performs the following:

- Invokes `eliminateClassicEventDelegation()` to remove all events associated
  with Ember's EventDispatcher to reduce its runtime overhead and ensure that
  it is effectively not in use.

- Invokes `rewireClassicComponentEvents(app)` to rewire each Classic
  component to add its own event listeners for standard event handlers (e.g.
  `click`, `mouseDown`, `submit`, etc.).

- Configures an instance initializer that invokes
  `rewireActionModifier(appInstance)` to redefine the `action` modifier with
    a substitute that uses `addEventListener`.

Additional changes include:
* d-button: only preventDefault / stopPropagation for handled actions
   This allows unhandled events to propagate as expected.
* d-editor: avoid adding duplicate event listener for tests
   This extra event listener causes duplicate paste events in tests.
* group-manage-email-settings: Monitor `input` instead of `change` event for checkboxes
2022-10-26 14:44:12 +01:00
David Taylor
4c4ac9cc47
Revert "DEV: Normalize event handling to improve Glimmer + Classic component compat (#18490)" (#18725)
This reverts commit 28be5d3037 and fcb4675415

This caused qunit timeouts in our internal CI environments. Not sure of the exact cause yet, but we're reverting for now while we investigate.
2022-10-24 18:30:08 +01:00
Dan Gebhardt
28be5d3037
DEV: Normalize event handling to improve Glimmer + Classic component compat (#18490)
Classic Ember components (i.e. "@ember/component") rely upon "event
delegation" to listen for events at the application root and then dispatch
those events to any event handlers defined on individual Classic components.
This coordination is handled by Ember's EventDispatcher.

In contrast, Glimmer components (i.e. "@glimmer/component") expect event
listeners to be added to elements using modifiers (such as `{{on "click"}}`).
These event listeners are added directly to DOM elements using
`addEventListener`. There is no need for an event dispatcher.

Issues may arise when using Classic and Glimmer components together, since it
requires reconciling the two event handling approaches. For instance, event
propagation may not work as expected when a Classic component is nested
inside a Glimmer component.

`normalizeEmberEventHandling` helps an application standardize upon the
Glimmer event handling approach by eliminating usage of event delegation and
instead rewiring Classic components to directly use `addEventListener`.

Specifically, it performs the following:

- Invokes `eliminateClassicEventDelegation()` to remove all events associated
  with Ember's EventDispatcher to reduce its runtime overhead and ensure that
  it is effectively not in use.

- Invokes `rewireClassicComponentEvents(app)` to rewire each Classic
  component to add its own event listeners for standard event handlers (e.g.
  `click`, `mouseDown`, `submit`, etc.).

- Configures an instance initializer that invokes
  `rewireActionModifier(appInstance)` to redefine the `action` modifier with
    a substitute that uses `addEventListener`.

Additional changes include:
* d-button: only preventDefault / stopPropagation for handled actions
   This allows unhandled events to propagate as expected.
* d-editor: avoid adding duplicate event listener for tests
   This extra event listener causes duplicate paste events in tests.
* group-manage-email-settings: Monitor `input` instead of `change` event for checkboxes
2022-10-24 16:06:11 +01:00
Bianca Nenciu
33087f0bdf
A11Y: Set role=presentation if alt attr is missing (#18546)
This applies to all images posted that do not have a user description.
2022-10-12 14:07:37 +03:00
Keegan George
15f192447b
FIX: Ability to trigger emoji after indented code block (#18478) 2022-10-05 10:33:08 -07:00
Dan Gebhardt
03b7b7d1bc
DEV: Remove usage of {{action}} modifiers - Take 2 (#18476)
This PR enables the [`no-action-modifiers`](https://github.com/ember-template-lint/ember-template-lint/blob/master/docs/rule/no-action-modifiers.md) template lint rule and removes all usages of the `{{action}}` modifier in core.

In general, instances of `{{action "x"}}` have been replaced with `{{on "click" (action "x")}}`. 

In many cases, such as for `a` elements, we also need to prevent default event handling to avoid unwanted side effects. While the `{{action}}` modifier internally calls `event.preventDefault()`, we need to handle these cases more explicitly. For this purpose, this PR also adds the [ember-event-helpers](https://github.com/buschtoens/ember-event-helpers) dependency so we can use the `prevent-default` handler. For instance:

```
<a href {{on "click" (prevent-default (action "x"))}}>Do X</a>
```

Note that `action` has not in general been refactored away as a helper yet. In general, all event handlers should be methods on the corresponding component and referenced directly (e.g. `{{on "click" this.doSomething}}`). However, the `action` helper is used extensively throughout the codebase and often references methods in the `actions` hash on controllers or routes. Thus this refactor will also be extensive and probably deserves a separate PR.

Note: This work was done to complement #17767 by minimizing the potential impact of the `action` modifier override, which uses private API and arguably should be replaced with an AST transform.

This is a followup to #18333, which had to be reverted because it did not account for the default treatment of modifier keys by the {{action}} modifier.

Commits:
* Enable `no-action-modifiers` template lint rule
* Replace {{action "x"}} with {{on "click" (action "x")}}
* Remove unnecessary action helper usage
* Remove ctl+click tests for user-menu
   These tests now break in Chrome when used with addEventListener. As per the comment, they can probably be safely removed.
* Prevent default event handlers to avoid unwanted side effects
   Uses `event.preventDefault()` in event handlers to prevent default event handling. This had been done automatically by the `action` modifier, but is not always desirable or necessary.
* Restore UserCardContents#showUser action to avoid regression
   By keeping the `showUser` action, we can avoid a breaking change for plugins that rely upon it, while not interfering with the `showUser` argument that's been passed.
* Revert EditCategoryTab#selectTab -> EditCategoryTab#select
   Avoid potential breaking change in themes / plugins
* Restore GroupCardContents#showGroup action to avoid regression
   By keeping the `showGroup` action, we can avoid a breaking change for plugins that rely upon it, while not interfering with the `showGroup` argument that's been passed.
* Restore SecondFactorAddTotp#showSecondFactorKey action to avoid regression
   By keeping the `showSecondFactorKey` action, we can avoid a breaking change for plugins that rely upon it, while not interfering with the `showSecondFactorKey` property that's maintained on the controller.
* Refactor away from `actions` hash in ChooseMessage component
* Modernize EmojiPicker#onCategorySelection usage
* Modernize SearchResultEntry#logClick usage
* Modernize Discovery::Categories#showInserted usage
* Modernize Preferences::Account#resendConfirmationEmail usage
* Modernize MultiSelect::SelectedCategory#onSelectedNameClick usage
* Favor fn over action in SelectedChoice component
* Modernize WizardStep event handlers
* Favor fn over action usage in buttons
* Restore Login#forgotPassword action to avoid possible regression
* Introduce modKeysPressed utility
   Returns an array of modifier keys that are pressed during a given `MouseEvent` or `KeyboardEvent`.
* Don't interfere with click events on links with `href` values when modifier keys are pressed
2022-10-05 13:08:54 +01:00
Osama Sayegh
4d05e3edab
DEV: Include pending reviewables in the main tab in the user menu (#18471)
This commit makes pending reviewables show up in the main tab (a.k.a. "all notifications" tab). Pending reviewables along with unread notifications are always shown first and they're sorted based on their creation date (most recent comes first).

The dismiss button currently only shows up if there are unread notifications and it doesn't dismiss pending reviewables. We may follow up with another change soon that allows makes the dismiss button work with reviewables and remove them from the list without taking any action on them. 

Follow-up to 079450c9e4.
2022-10-05 12:30:02 +03:00
Martin Brennan
8ebd5edd1e
DEV: Rename secure_media to secure_uploads (#18376)
This commit renames all secure_media related settings to secure_uploads_* along with the associated functionality.

This is being done because "media" does not really cover it, we aren't just doing this for images and videos etc. but for all uploads in the site.

Additionally, in future we want to secure more types of uploads, and enable a kind of "mixed mode" where some uploads are secure and some are not, so keeping media in the name is just confusing.

This also keeps compatibility with the `secure-media-uploads` path, and changes new
secure URLs to be `secure-uploads`.

Deprecated settings:

* secure_media -> secure_uploads
* secure_media_allow_embed_images_in_emails -> secure_uploads_allow_embed_images_in_emails
* secure_media_max_email_embed_image_size_kb -> secure_uploads_max_email_embed_image_size_kb
2022-09-29 09:24:33 +10:00
Penar Musaraj
cc4af80c7d
DEV: refactor bootbox alerts (#18292) 2022-09-27 14:47:13 -04:00
Keegan George
a23d19fab0
DEV: Emoji picker keyboard accessibility updates (#18331)
This PR makes some updates to the prior keyboard accessibility commit (eb98746):
- Makes `tabindex` attribute only appear on emoji markup in the emoji picker.
- After pressing the Esc key, focus returns to the <textarea/> input (composer editor or chat input)
2022-09-22 15:21:34 -07:00
Rafael dos Santos Silva
f11b926823
DEV: Add test case for syntax highlight of complex HTML (#18320)
* DEV: Add test case for syntax highlight of complex HTML

The commit 685e0da upgrade HighlightJS to version 11, which deprecates
syntax highlight of complex HTML elements. See https://github.com/highlightjs/highlight.js/issues/2889

This brought a regression of syntax highlighting of GitHub oneboxes,
which was fixed in 09cec7d. This commit adds a test case to prevent
future regressions like this one.

* fix test and warning
2022-09-21 19:09:53 -03:00
Keegan George
eb987460f2
FEATURE: Select emojis in picker via keyboard (#18163)
* DEV: Make emoji elements focusable

Since emoji elements are of type `<img>` it requires a `tablindex="0"` in order to be focusable.

* WIP: Handle emoji focus/selection via arrow keys

Near completion, however, need a few fixes/improvements and overall code cleanup

* WIP: Testing

* DEV: Fixes and cleanup

* DEV: Follow conventions

* DEV: Improve up/down traversal when recents present

* DEV: Emoji markup in tests should include `tabindex`

* DEV: Add `tabindex` to topic tests

* DEV: Variable name as `searchInput` instead of `searchBar`

* DEV: Use appropriate method name (`_setNumEmojiPerRow`)

* DEV: Add comments and avoid nested if

* WIP: Adding test

* Fix first test

* DEV: Add assertions for arrow keys and escape key

* Some fixes for up/down navigation

This does not fix everything, when going from one section to another,
there are issues

* Fix a small regression

* FIX: Ability to focus on search results

Fixes regression

* Refactor calculating next up/down emoji

* Debugging test failure

* Skip stubborn CI test, add others

Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
2022-09-21 13:21:36 -07:00
Jarek Radosz
eab33af5bf
SECURITY: Handle incomplete quote bbcode (#18311) 2022-09-21 14:02:50 +02:00
Osama Sayegh
3d2de7ca03
FIX: Add missing string for reviewables in user menu when reviewable post is deleted (#18295) 2022-09-21 09:05:08 +10:00
Penar Musaraj
2704a02e3a
FIX: In-page anchor links were broken in subfolder setups (#18250)
The key fix in this commit is that it removes `this.replaceState(path)` for anchor-only URLs. We still intercept those routing changes to properly calculate the scroll position of the anchor via `jumpToElement`, but we no longer use the Ember router to override the browser's history. This fixes the subfolder issue and also lets the browser maintain its history correctly.

The commit also includes a small refactor to the `jumpToElement` helper to facilitate stubbing in tests.
2022-09-15 08:09:34 -04:00
Andrei Prigorshnev
b6e0219a74
DEV: extract until date formatting in a library function (#18003) 2022-08-29 15:45:36 +04:00
Jarek Radosz
87f5715878
DEV: Keep global state reset in a single place (#18049) 2022-08-23 21:09:37 +02:00
Joffrey JAFFEUX
4e3c688d65
DEV: implements removeKeys(predicate) in keyValueStore (#18019) 2022-08-21 19:19:25 +02:00
Jarek Radosz
dc5dc78309
DEV: Use async and sinon.resolves instead of rsvp (#18001)
…in tests
2022-08-20 11:20:55 +02:00
Osama Sayegh
75599fb88e
DEV: Refactor new user menu files (#17879)
This commit includes the changes proposed in #17823. I've made these changes so that plugins that need to add tabs/lists with mixed item types - like the bookmarks tab that displays notifications and bookmarks - to the menu, don't have to write 2 templates like we currently do for the bookmarks/messages tabs (see user-menu/bookmark-notification-item.js that has been deleted in this commit).
2022-08-16 10:37:56 +08:00
Joffrey JAFFEUX
7476c22324
DEV: implements parseAsync in discourse/lib/text (#17899)
`parseAsync` allows to parse a block of markdown into tokens.

Usage:

```javascript
import { parseAsync } from "discourse/lib/text";

// ...

await parseAsync("**test**").then((tokens) => {
 console.log(tokens);
})
```
2022-08-13 14:25:32 +02:00
Osama Sayegh
69664d2153
DEV: Make group message summary notification Link to the group inbox (#17884)
This fix is for the experimental user menu.
2022-08-12 15:15:43 +03:00
Osama Sayegh
b5a6015155
DEV: Fallback to bookmarkable_url if bookmark reminder notification has no topic info (#17883)
This fix is for the experimental user menu. Some `bookmark_reminder` notifications may not be associated with a topic/post (e.g. bookmark reminder for a chat message) in which case the default notification renderer cannot figure out the `href` for those `bookmark_reminder` notifications. This commit teaches the `bookmark_reminder` notification type renderer to fallback to `bookmarkable_url` that's present in the notification data if the default notification renderer doesn't return a `href` for the notification.
2022-08-12 14:40:44 +03:00
Osama Sayegh
0df1c4eab2
DEV: Refactor notification/reviewable items rendering in the new user menu (#17792)
Prior to this commit, we had a default Glimmer component that was responsible for handling generic rendering of notifications in the user menu, and many notification types had a custom Glimmer component that inherited from the default component to customize how they were rendered. That implementation was less than ideal because it meant plugins would have to create Glimmer components to customize notification types added by them and that would make the surface area of the API too big.

This commit changes the implementation so there's only one Glimmer component for rendering notifications, and then notification types that need to be customized can create a regular JavaScript class - `renderDirector` in the code - that provides the Glimmer component with the content it should display. We also introduce an API for plugins to register a renderer for a notification type or override an existing one.

Some of the changes are partially extracted from https://github.com/discourse/discourse/pull/17379.
2022-08-05 07:55:00 +03:00
Osama Sayegh
53dd9b0c66
DEV: Add aria-label option to the d-icon helper (#17741)
Extracted from https://github.com/discourse/discourse/pull/17379.
2022-08-03 09:33:50 +03:00
Selase Krakani
862007fb18
FEATURE: Add support for case-sensitive Watched Words (#17445)
* 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.
2022-08-02 10:06:03 +02:00
Jarek Radosz
7980c41832
DEV: Fix fake-timer issues (#17681)
Occasionally some code (e.g. live-reload) would try to clear a timer that was set up before fake timers were installed. That would lead to issues and warnings. Enabling `shouldClearNativeTimers` option fixes it.
2022-07-27 22:54:22 +02:00
Jarek Radosz
b179fb98b1
DEV: Consistently use response helper (#17627) 2022-07-25 02:31:52 +02:00
Jarek Radosz
cb40e4c322
DEV: Use a separate KVS namespace for tests (#17591) 2022-07-21 15:27:24 +02:00
Jarek Radosz
1ccabe62d6
DEV: Move emoji-store test to the correct dir (#17544) 2022-07-17 23:44:10 +02:00
Jarek Radosz
5538b8442e
DEV: Introduce discourseLater (#17532)
A wrapper for `later()` from `@ember/runloop`, similar to `discourseDebounce`. It automatically reduces the delay in testing environment.
2022-07-17 00:50:49 +02:00
Jarek Radosz
7b6cd44c32
DEV: Remove most of jQuery usage from tests (#17474) 2022-07-13 19:29:19 +02:00
Jarek Radosz
0d6929d935
DEV: Avoid triggering 404 errors in tests (#17404) 2022-07-10 11:09:13 +02:00
Jarek Radosz
c3fd91670e
DEV: Update linting setup and fix issues (#17345)
Re-lands #16119 and #17298

* Update eslint-config-discourse
* Update linting workflow
* Prettier-ignore stuff
* Update template-lint config
* Auto-fix template issues
* Fix various template issues
  Mostly incorrect attributes and unused templates
* Prettier js files
* Fix template auto-fix regressions
* Small css tweak

Co-authored-by: Peter Wagenet <peter.wagenet@gmail.com>
2022-07-06 10:37:54 +02:00
Jarek Radosz
bfeee1b803
DEV: Update sinon (#17266) 2022-06-28 21:21:51 +02:00
Jarek Radosz
011a16cb8a
DEV: Rename translatedtitle to translatedTitle (#17160) 2022-06-20 12:28:05 -06:00
Gerhard Schlager
1c6f8f8a36
DEV: Upgrade Markdown.it to v13.0.1 (#17099)
Updates markdown-it to v13.0.1

Noteworthy changes:
* `markdownit()` is now available on `globalThis` instead of `window`.

* The `text_collapse` rule was renamed to `fragments_join` which affected the `bbcode-inline` implementation.

* The `linkify` rule was added to the `inline` chain which affected the handling of the `[url]` BBCode. If available, our implementation reuses `link_open` and `link_close` tokens created by linkify in order to prevent duplicate links.

* The rendered HTML for code changed slightly. There's now a linebreak before the `</code>` tag. The tests were adjusted accordingly.
2022-06-20 15:25:13 +02:00
Gerhard Schlager
888f50543d
DEV: Fix javascript:update rake task (#17098)
* The `javascript:update` rake task failed because recent versions of chart.js use a lowercase filename (`chart.min.js` instead of `Chart.min.js`)

* Changed `loadScript()` to use lowercase keys to lookup scripts

* `svg-arrow.css` seems to have changed slightly (linebreak at the end of file)
2022-06-15 19:49:04 +02:00
Jeff Wong
9a656e18e9 DEV: add translation fallback option for i18n
Allow for a default translation string to be returned when a translation cannot
be found.

Useful in contexts where there is a known fallback, such as custom emoji group
strings.
2022-06-10 11:10:05 -10:00
Jarek Radosz
711cd7c85d
DEV: Add to-markdown decorator functions (#16943)
To be used in discourse-spoiler-alert
2022-05-31 11:06:41 +02:00
Jarek Radosz
d065ec0f7b
FIX: Correctly handle nested quotes in to-markdown (#16938)
Given this html:

```
<aside class="quote no-group">
  <blockquote>
    <aside class="quote no-group">
      <blockquote>
        <p dir="ltr">test</p>
      </blockquote>
    </aside>
    <p dir="ltr">test2</p>
  </blockquote>
</aside>
```

The result was an invalid markdown:

```
[quote]
[quote]
> test
> [/quote]
>
>
>
> test2
[/quote]
```

Now the result is:

```
[quote]
[quote]
test
[/quote]

test2
[/quote]
```
2022-05-27 22:05:43 +02:00
Andrei Prigorshnev
187922d51c
FEATURE: introduce a sitewide setting for disabling suggesting weekends in time pickers (#16563) 2022-05-02 15:40:23 +04:00
Andrei Prigorshnev
c9b2374299
DEV: make API of future-date-input more customizable and aligned with the API of time-shortcut-picker (#16502) 2022-04-27 16:41:15 +04:00
Andrei Prigorshnev
42bb629817
DEV: use the only source for time shortcut options on all date pickers (#16366) 2022-04-21 15:49:11 +04:00
Isaac Janzen
196b791365
DEV: Prioritize full name when display_name_on_posts active (#16078)
See: https://meta.discourse.org/t/display-full-name-not-username-when-attributing-quote-or-reply/203533?u=isaacjanzen for context

The initial release [broke quoting](https://meta.discourse.org/t/quoting-broken-when-name-matches-username/217633?u=isaacjanzen) but we now pass the username when 
```
siteSettings.display_name_on_posts && !siteSettings.prioritize_username_in_ux && post.name
```
as well as the full name to guarantee that we are not getting any mismatches when querying for user / avatar.

eg. 
```
[quote="Isaac Janzen, post:3, topic:7, full:true, username:isaac.janzen"]
bing bong
[/quote]
```
2022-04-20 10:07:51 -05:00
Bianca Nenciu
f3ef69e27d
FIX: Add missing translations for medium format (#16517)
Commit 68497bddf2 implemented a function
to format durations in a medium format, similar to how durationTiny did.
The existent translation strings do not cover all cases and this commit
adds the missing translation strings.
2022-04-20 14:49:08 +03:00
Martin Brennan
cecdef83a8
FIX: Fall back to clipboard.writeText if ClipboardItem not supported (#16419)
Firefox does not support window.ClipboardItem yet (it is behind
a flag (dom.events.asyncClipboard.clipboardItem) as at version 87.)
so we need to fall back to the normal non-async clipboard copy, that
works in every browser except Safari.

This commit also tests the clipboardCopyAsync function by stubbing out
the clipboard on the window.navigator.

This fixes an issue in the discourse-chat plugin, where the
"Quote in Topic" button errored in Firefox.
2022-04-11 13:00:45 +10:00
Andrei Prigorshnev
8a9c644021
FIX: no need to hide "Later This Week" when showing "Later Today" (#16365) 2022-04-05 16:49:05 +04:00
Bianca Nenciu
ac612987ef
FIX: Build correct post and topic shareUrl (#16332)
The links returned by post.url and topic.url are relative, but contain
the subdirectory. When getAbsoluteURL is called to construct the
complete share URL, it adds the host and the subdirectory again. As a
result the created URLs contained the subdirectory twice.
2022-04-01 00:02:01 +03:00