Skip to content

[CLEANUP] Remove old browser workarounds, targeting Ember 6.x#21204

Open
johanrd wants to merge 10 commits intoemberjs:mainfrom
johanrd:cleanup/remove-old-browser-workarounds
Open

[CLEANUP] Remove old browser workarounds, targeting Ember 6.x#21204
johanrd wants to merge 10 commits intoemberjs:mainfrom
johanrd:cleanup/remove-old-browser-workarounds

Conversation

@johanrd
Copy link
Contributor

@johanrd johanrd commented Mar 8, 2026

See Ember 6.x browser support: https://emberjs.com/browser-support/

Cowritten by claude

Is globalThis safe in all target environments including Node/SSR?

globalThis is supported since Chrome 71, Firefox 65, Safari 12.1, Edge 79, and Node.js 12.0.0. Ember 6.x targets Chrome >= 109, Firefox >= 115, Safari >= 15.6, Edge >= 128, Node >= 18 — all well above the minimum.

Popstate workaround removal — are we sure no target browser fires popstate on initial page load?

Chrome fixed this in v34 (https://bugs.chromium.org/p/chromium/issues/detail?id=63040). Firefox 'never' had the bug it seems. Safari fixed it in 9.1, see mdn/content#43368 (comment)

event.button !== 0 vs event.which > 1 — is this a behavior change?

No. MouseEvent.button (standard, returns 0 for primary click) and UIEvent.which (deprecated, returns 1 for primary click) both correctly identify non-primary clicks in all target browsers. The old which > 1 check existed because IE9 could return undefined for which, which is irrelevant for Ember 6.x targets.

isEdge export removal — could this break addons?

It's exported from internal-test-helpers, which is a private workspace-internal package, not published to npm. The export was unused even within this repo.

ClientRect → DOMRect type change — is this a public API?

getViewBoundingClientRect is marked @Private and is only intended for dev tools like Ember Inspector. The change is also a no-op at runtime since Range.getBoundingClientRect() already returns DOMRect in all target browsers.

Should this target 6.x or wait for 7.0?

Should be safe for 6.x. None of these changes alter user-facing behavior — they remove dead code paths that could never execute in target browsers.

@johanrd johanrd changed the title [CLEANUP] Cleanup/remove old browser workarounds for Ember 6.x [CLEANUP] Remove old browser workarounds for Ember 6.x Mar 8, 2026
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this test safe to remove?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess if we don't support the browser this was intended for? (based on the history location changes below)

Copy link
Contributor Author

@johanrd johanrd Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test validated the _previousURL workaround (asserting this._previousURL === this.getURL() after initState). Since the workaround is removed, the property no longer exists. The underlying behavior (popstate not firing on page load) shouln't need a test — it's browser behavior, not Ember logic?

Chrome fixed it in v34 (Jan 2014): https://bugs.chromium.org/p/chromium/issues/detail?id=63040.
All Ember 6.x target browsers (Chrome >= 109, Safari >= 15.6, Firefox >= 115, Edge >= 128) are unaffected.
Manually verified on current Safari and Safari 15.3 as well with this gist

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But be ware that the above is my understanding of this. MDN still states that "Safari always emit a popstate event on page load" (see popstate_event#the_history_stack). I couldn't reproduce, so I did file a bug at MDN mdn/content#43368

If someone has access to older safaris (through browserstack?), it could be useful to pinpoint a version (if my gist is even valid)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, this fits our minimum supported browser versions, per: https://emberjs.com/browser-support/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now tried in browserstack, and I can verify that Safari fixed this between v8.0 and 9.1, see mdn/content#43368 (comment)

…RectList, unused function, and avoid declaring global types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was this removed?

Copy link
Contributor Author

@johanrd johanrd Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment referenced an EdgeHTML bug (which is dead since Edge switched to Chromium in Jan 2020), so the comment was misleading/outdated. The setDebugFunction call from 5bbd43e is itself is kept. It could still serve well as a defensive afterEach cleanup in case callWithStub's finally block ever doesn't run? but not sure if needed

@johanrd johanrd force-pushed the cleanup/remove-old-browser-workarounds branch from 25613a2 to b641aeb Compare March 8, 2026 16:17
checkGlobal(typeof window === 'object' && window) ||
(typeof mainContext !== 'undefined' && mainContext) || // set before strict mode in Ember loader/wrapper
new Function('return this')(); // eval outside of strict mode
export default globalThis as unknown as EmberGlobal;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot where is this used?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(also @johanrd <3)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be cleaned up later probably -- there is an IIFE here that needs some looking in to

Copy link
Contributor Author

@johanrd johanrd Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NullVoxPopuli Good call. That would look something like this: Proposed cleanup commit: johanrd@4be5c06, full diff: https://github.com/johanrd/ember.js/pull/10/changes

It seems like a good fix, but testing it on you now, before I make it part of this PR.

Copy link
Contributor Author

@johanrd johanrd Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Included the cleanup now

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes legacy browser workarounds and IE/old-Edge compatibility paths throughout Ember’s runtime, routing, and internal test helpers, aligning the codebase with Ember 6.x’s supported browser/runtime matrix.

Changes:

  • Replace legacy global/object detection and timing fallbacks with modern primitives (globalThis, performance.now()), and remove browser-specific workarounds (IE/Edge/WebKit).
  • Simplify routing/location behavior by relying on location.origin and removing the initial popstate workaround logic.
  • Update test utilities and integration tests to use modern event constructors (Event, MouseEvent, KeyboardEvent) and remove old-environment conditionals.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/loader/lib/index.js Switch global lookup logic to rely on globalThis.
packages/internal-test-helpers/lib/system/synthetic-events.ts Use direct MouseEvent/KeyboardEvent constructors and simplify focus checks.
packages/internal-test-helpers/lib/matchers.ts Remove IE-specific matcher comment while keeping normalization behavior.
packages/internal-test-helpers/lib/equal-inner-html.ts Remove IE SVG innerHTML normalization path.
packages/internal-test-helpers/lib/ember-dev/assertion.ts Remove Edge-specific comment/workaround note in teardown.
packages/internal-test-helpers/lib/browser-detect.ts Remove unused Edge detection helper.
packages/internal-test-helpers/index.ts Stop exporting removed Edge detection helper.
packages/@glimmer/runtime/lib/dom/props.ts Clarify attribute override rationale with modern DOM semantics.
packages/@ember/runloop/tests/later_test.js Update comments to reflect modern browser behavior.
packages/@ember/routing/tests/location/util_test.js Update mocks to use location.origin.
packages/@ember/routing/tests/location/history_location_test.js Remove test for legacy popstate workaround.
packages/@ember/routing/tests/location/hash_location_test.js Use new Event('hashchange') instead of legacy createEvent.
packages/@ember/routing/lib/location-utils.ts Remove getOrigin fallback and use location.origin directly.
packages/@ember/routing/history-location.ts Remove initial popstate workaround state tracking.
packages/@ember/object/mixin.ts Drop IE11 WeakMap/sealed-object priming path in DEBUG.
packages/@ember/instrumentation/index.ts Use performance.now() directly for timing.
packages/@ember/debug/index.ts Always freeze in debugFreeze (removes old Chrome-era optimization).
packages/@ember/-internals/views/lib/system/utils.ts Update click detection logic and modernize rect typing.
packages/@ember/-internals/metal/lib/property_get.ts Remove IE-era guidance from docs and modernize wording.
packages/@ember/-internals/glimmer/tests/integration/syntax/each-test.js Remove IE11 Set-construction workaround in tests.
packages/@ember/-internals/glimmer/tests/integration/event-dispatcher-test.js Use new Event and remove conditional test gating.
packages/@ember/-internals/glimmer/tests/integration/components/utils-test.js Update rect assertions to modern DOM types.
packages/@ember/-internals/glimmer/tests/integration/components/textarea-curly-test.js Use new Event instead of legacy createEvent.
packages/@ember/-internals/glimmer/tests/integration/components/textarea-angle-test.js Use new Event instead of legacy createEvent.
packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js Remove URL normalization helper and assert directly on href attributes.
packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js Remove URL normalization helper and modernize click event creation.
packages/@ember/-internals/glimmer/tests/integration/components/input-curly-test.js Use new Event instead of legacy createEvent.
packages/@ember/-internals/glimmer/tests/integration/components/input-angle-test.js Use new Event instead of legacy createEvent.
packages/@ember/-internals/environment/lib/global.ts Replace complex global detection with globalThis + explicit Ember global typing.
packages/@ember/-internals/environment/lib/env.ts Rely on inferred EmberENV type from global typing.
eslint.config.mjs Add modern DOM globals for linting in packages JS files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

NullVoxPopuli
NullVoxPopuli previously approved these changes Mar 8, 2026
@johanrd johanrd changed the title [CLEANUP] Remove old browser workarounds for Ember 6.x [CLEANUP] Remove old browser workarounds targeting Ember 6.x Mar 9, 2026
@johanrd johanrd changed the title [CLEANUP] Remove old browser workarounds targeting Ember 6.x [CLEANUP] Remove old browser workarounds, targeting Ember 6.x Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants