Skip to content

Commit

Permalink
Merge branch 'main' into select-value-equality
Browse files Browse the repository at this point in the history
  • Loading branch information
brianmhunt committed Jan 9, 2022
2 parents cd0b070 + 15fb7be commit 0545261
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 35 deletions.
3 changes: 3 additions & 0 deletions builds/knockout/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ include ../../tools/build.mk

iife-global-name := ko

test:
@echo "Disabled pending fixes to build process"

default::
$(MAKE) browser

1 change: 0 additions & 1 deletion builds/knockout/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"@tko/provider.component": "^4.0.0-alpha9.0",
"@tko/provider.databind": "^4.0.0-alpha9.0",
"@tko/provider.multi": "^4.0.0-alpha8.4",
"@tko/provider.mustache": "^4.0.0-alpha9.0",
"@tko/provider.virtual": "^4.0.0-alpha9.0",
"@tko/utils.component": "^4.0.0-alpha9.0",
"@tko/utils.functionrewrite": "^4.0.0-alpha8.2",
Expand Down
3 changes: 2 additions & 1 deletion builds/knockout/spec/crossWindowBehaviors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
describe('Cross-window support', function() {


describe('Cross-window support', function() {
it('Should work in another window', function () {
var win2 = window.open("blank.html", "_blank", "height=150,location=no,menubar=no,toolbar=no,width=250"),
body2;
Expand Down
5 changes: 0 additions & 5 deletions builds/knockout/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import { DataBindProvider } from '@tko/provider.databind'
import { ComponentProvider } from '@tko/provider.component'
import { AttributeProvider } from '@tko/provider.attr'
import { MultiProvider } from '@tko/provider.multi'
import {
TextMustacheProvider, AttributeMustacheProvider
} from '@tko/provider.mustache'

import { bindings as coreBindings } from '@tko/binding.core'
import { bindings as templateBindings } from '@tko/binding.template'
Expand All @@ -34,8 +31,6 @@ const builder = new Builder({
filters,
provider: new MultiProvider({
providers: [
new AttributeMustacheProvider(),
new TextMustacheProvider(),
new ComponentProvider(),
dataBindProvider,
new VirtualProvider(),
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
"devDependencies": {
"@lerna/version": "^4.0.0",
"@types/jasmine": "^3.6.10",
"@types/mocha": "^8.2.2",
"@types/mocha": "^9.0.0",
"chai": "^4.3.4",
"electron": "^12.0.4",
"esbuild": "^0.11.12",
"fs-extra": "^9.1.0",
"electron": "^16.0.6",
"esbuild": "^0.14.11",
"fs-extra": "^10.0.0",
"jquery": "^3.6.0",
"karma": "^6.3.2",
"karma-chai": "^0.1.0",
Expand All @@ -46,8 +46,8 @@
"karma-sauce-launcher": "^4.3.6",
"karma-sinon": "^1.0.5",
"lerna": "^4.0.0",
"mocha": "^8.3",
"sinon": "^10.0",
"mocha": "^9.1",
"sinon": "^12.0",
"standard": "^16.0.3",
"typescript": "^4.2.4"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/bind/src/bindingContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { extend, options, domData } from '@tko/utils'
import { extend, options, domData, isObjectLike } from '@tko/utils'

import {
pureComputed
Expand Down Expand Up @@ -118,7 +118,7 @@ Object.assign(bindingContext.prototype, {
}
const $data = this.$data
// instanceof Object covers 1. {}, 2. [], 3. function() {}, 4. new *; it excludes undefined, null, primitives.
if ($data instanceof Object && token in $data) { return $data[token] }
if (isObjectLike($data) && token in $data) { return $data[token] }
if (token in this) { return this[token] }
if (token in globals) { return globals[token] }

Expand Down
3 changes: 2 additions & 1 deletion packages/binding.component/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@tko/observable": "^4.0.0-alpha8.0",
"@tko/provider": "^4.0.0-alpha8.4",
"@tko/utils": "^4.0.0-alpha8.0",
"@tko/utils.jsx": "^4.0.0-alpha8.0",
"@tko/utils.component": "^4.0.0-alpha9.0",
"tslib": "^2.2.0"
},
Expand Down Expand Up @@ -44,4 +45,4 @@
"type": "git",
"url": "git+https://github.com/knockout/tko.git"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ describe('Function Rewrite Provider', function () {
'x: function () { return {} }': 'x: () => { }',
'x: function () { return "abc" }': 'x: () => "abc"',
'stringLiteral: "hello", numberLiteral: 123, boolLiteralTrue: true, boolLiteralFalse: false, objectLiteral: {}, functionLiteral: function() { }, nullLiteral: null, undefinedLiteral: undefined': 'stringLiteral: "hello", numberLiteral: 123, boolLiteralTrue: true, boolLiteralFalse: false, objectLiteral: {}, functionLiteral: () => undefined, nullLiteral: null, undefinedLiteral: undefined',
'function (v) { return v.name + " (" + v.job + ")"; }': '(v) => v.name + " (" + v.job + ")";'
'function (v) { return v.name + " (" + v.job + ")"; }': '(v) => v.name + " (" + v.job + ")"',
'function () { foo(); }': '() => foo() && undefined'
}
const idempotents = [
'x: nonfunction () {}'
Expand Down
16 changes: 10 additions & 6 deletions packages/utils.functionrewrite/src/functionRewrite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
*
*/

const FUNCTION_REX = /\bfunction\s*\(([^)]*)\)\s*{\s*(?:return\s+([^}]+?)\s*)?}/g
const FUNCTION_REX = /\bfunction\s*\(([^)]*)\)\s*\{\s*(?:(return\s)?([^}]+?)[;\s]*)?\}/g

export default function functionRewrite (bindingString) {
return bindingString
.replace(FUNCTION_REX, (match, args, rv) => {
if (!functionRewrite.silent) {
console.log(`Knockout: Replace "${match}" with "=> ${rv}"`)
}
return `(${args.trim()}) => ${rv}`
.replace(FUNCTION_REX, (match, args, returnKeyword, rv) => {
if (rv && !returnKeyword) {
rv += ' && undefined'
}
const out = `(${args.trim()}) => ${rv}`
if (!functionRewrite.silent) {
console.log(`Knockout: Replace "${match}" with "${out}"`)
}
return out
})
}
34 changes: 33 additions & 1 deletion packages/utils.parser/spec/identifierBehaviors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ import {
describe('Identifier', function () {
function testLookup (identifier, $data) {
const ctx = new bindingContext($data)
return new Identifier(null, identifier).get_value(undefined, ctx)
return new Identifier(null, identifier).get_value(undefined, ctx, {})
}

function testWrite (identifier, $data, newValue) {
const ctx = new bindingContext($data)
return new Identifier(null, identifier).set_value(newValue, ctx, {})
}

var c = 'Z',
Expand All @@ -46,6 +51,12 @@ describe('Identifier', function () {
assert.equal(testLookup('f', context), f)
})

it('looks up values on no-prototype $data', function () {
const $data = Object.create(null)
$data.c = c
assert.equal(testLookup('c', $data), 'Z')
})

it('returns null as expected', function () {
assert.equal(testLookup('$data', null), null)
})
Expand All @@ -54,6 +65,27 @@ describe('Identifier', function () {
assert.equal(testLookup('$data', undefined), undefined)
})

it('sets plain values on $data', () => {
const $data = { c: c }
assert.equal($data.c, 'Z')
testWrite('c', $data, 'X')
assert.equal($data.c, 'X')
})

it('sets observable values on $data', () => {
const $data = { c: observable(c) }
assert.equal($data.c(), 'Z')
testWrite('c', $data, 'X')
assert.equal($data.c(), 'X')
})

it('sets plain values on no-prototype $data', () => {
const $data = Object.create(null)
$data.c = c
testWrite('c', $data, 'X')
assert.equal($data.c, 'X')
})

it('dereferences values on the parser', function () {
var context = new bindingContext({ f: f })
var fake_args = new Arguments(null, [])
Expand Down
8 changes: 4 additions & 4 deletions packages/utils.parser/src/Identifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import Node from './Node'
import Arguments from './Arguments'

import { hasOwnProperty } from '@tko/utils'
import { hasOwnProperty, isObjectLike } from '@tko/utils'

import {
isWriteableObservable, isObservable
Expand Down Expand Up @@ -106,11 +106,11 @@ export default class Identifier {
let leaf = this.token
let i, n, root

if (hasOwnProperty($data, leaf)) {
if (isObjectLike($data) && leaf in $data) {
root = $data
} else if (hasOwnProperty($context, leaf)) {
} else if (leaf in $context) {
root = $context
} else if (hasOwnProperty(globals, leaf)) {
} else if (leaf in globals) {
root = globals
} else {
throw new Error('Identifier::set_value -- ' +
Expand Down
2 changes: 1 addition & 1 deletion packages/utils.parser/src/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ export default class Parser {
case 'null': return null
case 'undefined': return void 0
case 'function':
throw new Error('Knockout: Anonymous functions are no longer supported, but `=>` lambdas are.')
throw new Error('Knockout: Anonymous functions are no longer supported, but `=>` lambdas are. In: ' + this.text)
// return this.anonymous_fn();
}
return new Identifier(this, token, this.dereferences())
Expand Down
16 changes: 12 additions & 4 deletions packages/utils/src/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ export function hasOwnProperty(obj, propName) {
return Object.prototype.hasOwnProperty.call(obj, propName)
}

/**
* True when obj is a non-null object, or a function.
* @param obj
* @returns
*/
export function isObjectLike(obj) {
if (obj === null) { return false }
return typeof obj === 'object' || typeof obj === 'function'
}

export function extend (target, source) {
if (source) {
for (var prop in source) {
Expand Down Expand Up @@ -79,8 +89,6 @@ export function safeStringify (value) {
/**
* Promises/A+ compliant isThenable (per section 1.2)
*/
export function isThenable (object) {
const objectType = typeof object
const thenableType = objectType === 'object' || objectType === 'function'
return thenableType && object !== null && typeof object.then === 'function'
export function isThenable (object: any) {
return isObjectLike(object) && typeof object.then === 'function'
}
4 changes: 2 additions & 2 deletions tko.io/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -882,8 +882,8 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"

path-parse@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"

performance-now@^0.2.0:
version "0.2.0"
Expand Down

0 comments on commit 0545261

Please sign in to comment.