Skip to content

Commit 6629d63

Browse files
authored
Merge pull request #344 from knockout/modernize/utils-dead-polyfills
Modernize @tko/utils: drop dead polyfill probes
2 parents aaf3a03 + a38f5e4 commit 6629d63

18 files changed

Lines changed: 66 additions & 116 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
"@tko/utils": minor
3+
"@tko/utils.parser": patch
4+
"@tko/observable": patch
5+
"@tko/binding.core": patch
6+
"@tko/binding.foreach": patch
7+
"@tko/computed": patch
8+
"@tko/lifecycle": patch
9+
"@tko/builder": minor
10+
---
11+
12+
Drop dead polyfill probes from `@tko/utils`
13+
14+
Removes runtime feature detection for capabilities that all supported runtimes
15+
(modern browsers, Node, Bun, happy-dom) already expose unconditionally:
16+
17+
- `functionSupportsLengthOverwrite` + `overwriteLengthPropertyIfSupported`
18+
`Object.defineProperty(fn, 'length', …)` has worked since IE9. Call sites
19+
in `@tko/observable` now invoke `Object.defineProperty` directly.
20+
- `useSymbols` + `createSymbolOrString``Symbol` is always defined; call
21+
sites now use `Symbol(identifier)` directly. `createSymbolOrString` is no
22+
longer exposed on `ko.utils` (public API removal — minor bump for
23+
`@tko/utils` and `@tko/builder`).
24+
- `stringTrim` + `stringStartsWith` — removed; call sites use
25+
`String(value ?? '').trim()` / `value.startsWith(prefix)` inline.
26+
- `toggleDomNodeCssClass` SVGAnimatedString fallback — `classList` is
27+
available on every supported `Element` (including SVG since SVG2).
28+
- `parseJson` no longer routes through `stringTrim`; it trims inline when the
29+
input is a string.
30+
31+
`packages/utils.parser/src/preparse.ts` also guards `str.match(bindingToken)`
32+
against the `null` return case using `?? []` — previously relied on the match
33+
never returning `null` for the transformed input.

builds/knockout/spec/bindingAttributeBehaviors.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,6 @@ describe('Binding attribute syntax', function () {
260260
ko.applyBindings({}, testNode)
261261

262262
var allowedProperties = ['$parents', '$root', 'ko', '$rawData', '$data', '$parentContext', '$parent']
263-
if (ko.utils.createSymbolOrString('') === '') {
264-
allowedProperties.push('_subscribable')
265-
allowedProperties.push('_ancestorBindingInfo')
266-
}
267263
ko.utils.objectForEach(ko.contextFor(testNode.childNodes[0].childNodes[0]), function (prop) {
268264
expect(allowedProperties).to.contain(prop)
269265
})

packages/binding.core/src/css.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createSymbolOrString, toggleDomNodeCssClass, objectForEach, stringTrim } from '@tko/utils'
1+
import { toggleDomNodeCssClass, objectForEach } from '@tko/utils'
22

33
import { unwrap } from '@tko/observable'
44

@@ -12,11 +12,11 @@ export const css = {
1212
toggleDomNodeCssClass(element, className, shouldHaveClass)
1313
})
1414
} else {
15-
value = stringTrim(String(value || '')) // Make sure we don't try to store or set a non-string value
15+
value = String(value ?? '').trim() // Make sure we don't try to store or set a non-string value
1616
toggleDomNodeCssClass(element, element[css.classesWrittenByBindingKey], false)
1717
element[css.classesWrittenByBindingKey] = value
1818
toggleDomNodeCssClass(element, value, true)
1919
}
2020
},
21-
classesWrittenByBindingKey: createSymbolOrString('__ko__cssValue')
21+
classesWrittenByBindingKey: Symbol('__ko__cssValue')
2222
}

packages/binding.core/src/hasfocus.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { createSymbolOrString, triggerEvent, registerEventHandler } from '@tko/utils'
1+
import { triggerEvent, registerEventHandler } from '@tko/utils'
22

33
import { unwrap, dependencyDetection, isWriteableObservable } from '@tko/observable'
44

55
import type { AllBindings } from '@tko/bind'
66

7-
const hasfocusUpdatingProperty = createSymbolOrString('__ko_hasfocusUpdating')
8-
const hasfocusLastValue = createSymbolOrString('__ko_hasfocusLastValue')
7+
const hasfocusUpdatingProperty = Symbol('__ko_hasfocusUpdating')
8+
const hasfocusLastValue = Symbol('__ko_hasfocusLastValue')
99

1010
export const hasfocus = {
1111
init: function (element, valueAccessor, _allBindings: AllBindings) {

packages/binding.core/src/value.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { stringStartsWith, safeSetTimeout, tagNameLower, arrayForEach, selectExtensions } from '@tko/utils'
1+
import { safeSetTimeout, tagNameLower, arrayForEach, selectExtensions } from '@tko/utils'
22

33
import { unwrap, dependencyDetection } from '@tko/observable'
44

@@ -82,7 +82,7 @@ export class value extends BindingHandler {
8282
// This is useful, for example, to catch "keydown" events after the browser has updated the control
8383
// (otherwise, selectExtensions.readValue(this) will receive the control's value *before* the key event)
8484
let handler = this.valueUpdateHandler.bind(this)
85-
if (stringStartsWith(eventName, 'after')) {
85+
if (eventName.startsWith('after')) {
8686
handler = () => {
8787
// The elementValueBeforeEvent variable is non-null *only* during the brief gap between
8888
// a keyX event firing and the valueUpdateHandler running, which is scheduled to happen

packages/binding.foreach/src/foreach.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,7 @@
55
// Employing sound techniques to make a faster Knockout foreach binding.
66
// --------
77

8-
import {
9-
arrayForEach,
10-
cleanNode,
11-
options,
12-
virtualElements,
13-
createSymbolOrString,
14-
domData,
15-
domNodeIsContainedBy
16-
} from '@tko/utils'
8+
import { arrayForEach, cleanNode, options, virtualElements, domData, domNodeIsContainedBy } from '@tko/utils'
179

1810
import { isObservable, unwrap, observable } from '@tko/observable'
1911

@@ -87,7 +79,7 @@ function valueToChangeAddItem(value, index): ChangeAddItem {
8779
}
8880

8981
// store a symbol for caching the pending delete info index in the data item objects
90-
const PENDING_DELETE_INDEX_SYM = createSymbolOrString('_ko_ffe_pending_delete_index')
82+
const PENDING_DELETE_INDEX_SYM = Symbol('_ko_ffe_pending_delete_index')
9183

9284
export class ForEachBinding extends AsyncBindingHandler {
9385
// NOTE: valid valueAccessors include:

packages/builder/src/Builder.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
cleanNode,
1818
cloneNodes,
1919
compareArrays,
20-
createSymbolOrString,
2120
domData,
2221
extend,
2322
memoization,
@@ -116,7 +115,6 @@ export type Utils = {
116115
arrayRemoveItem: typeof arrayRemoveItem
117116
cloneNodes: typeof cloneNodes
118117
compareArrays: typeof compareArrays
119-
createSymbolOrString: typeof createSymbolOrString
120118
domData: typeof domData
121119
domNodeDisposal: typeof domNodeDisposal
122120
extend: typeof extend
@@ -149,7 +147,6 @@ const utils: Utils = {
149147
arrayRemoveItem,
150148
cloneNodes,
151149
compareArrays,
152-
createSymbolOrString,
153150
domData,
154151
domNodeDisposal,
155152
extend,

packages/computed/src/computed.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import {
77
addDisposeCallback,
88
arrayForEach,
9-
createSymbolOrString,
109
domNodeIsAttachedToDocument,
1110
extend,
1211
options,
@@ -28,7 +27,7 @@ import {
2827

2928
import type { Observable, Subscribable } from '@tko/observable'
3029

31-
const computedState: symbol = createSymbolOrString('_state')
30+
const computedState: symbol = Symbol('_state')
3231
const DISPOSED_STATE = {
3332
dependencyTracking: null,
3433
dependenciesCount: 0,

packages/lifecycle/src/LifeCycle.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { addDisposeCallback, createSymbolOrString } from '@tko/utils'
1+
import { addDisposeCallback } from '@tko/utils'
22

33
import { computed } from '@tko/computed'
44
import type { Observable } from '@tko/observable'
55

6-
const SUBSCRIPTIONS = createSymbolOrString('LifeCycle Subscriptions List')
7-
const ANCHOR_NODE = createSymbolOrString('LifeCycle Anchor Node')
6+
const SUBSCRIPTIONS = Symbol('LifeCycle Subscriptions List')
7+
const ANCHOR_NODE = Symbol('LifeCycle Anchor Node')
88

99
export default class LifeCycle {
1010
// NOTE: For more advanced integration as an ES6 mixin, see e.g.:

packages/observable/src/observable.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Observable values
33
// ---
44
//
5-
import { options, overwriteLengthPropertyIfSupported } from '@tko/utils'
5+
import { options } from '@tko/utils'
66

77
import * as dependencyDetection from './dependencyDetection'
88
import { deferUpdates } from './defer'
@@ -103,7 +103,7 @@ export function observable<T = any>(initialValue?: T): Observable {
103103
}
104104
}
105105

106-
overwriteLengthPropertyIfSupported(Observable as any, { value: undefined })
106+
Object.defineProperty(Observable, 'length', { value: undefined })
107107

108108
Observable[LATEST_VALUE] = initialValue
109109

0 commit comments

Comments
 (0)