Skip to content

Commit 782d01c

Browse files
authored
Merge pull request #215 from Auge19/fix_jquery
jquery) Fix loading jquery and add tests
2 parents caeb1e4 + ec83dfb commit 782d01c

File tree

21 files changed

+204
-94
lines changed

21 files changed

+204
-94
lines changed

.github/workflows/test-headless.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
strategy:
1515
matrix:
1616
node-version: [22.x]
17+
jquery: ['off','on']
1718

1819
steps:
1920
- name: Checkout code
@@ -31,5 +32,10 @@ jobs:
3132
- name: Run Build
3233
run: make
3334

34-
- name: Run Test-Headless
35+
- name: Run Test-Headless (without JQuery)
36+
if: "contains(${{ matrix.jquery }}, 'off')"
3537
run: make test-headless
38+
39+
- name: Run Test-Headless (with JQuery)
40+
if: "contains(${{matrix.jquery }}, 'on')"
41+
run: make test-headless-jquery

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ test:
2626
test-headless:
2727
$(LERNA) exec --stream -- $(MAKE) test-headless
2828

29+
test-headless-jquery:
30+
$(LERNA) exec --stream -- $(MAKE) test-headless-jquery
31+
2932
ci:
3033
$(LERNA) exec --stream --concurrency=1 -- $(MAKE) test-ci
3134

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ TKO aims to become a base for future versions of Knockout. The objectives inclu
100100
- CSP compliant
101101
- JSX/TSX support
102102

103+
## JQUERY and TKO
104+
105+
Optionally TKO can use JQuery for CSS-Manipulation and HTML-Templates (only if HTML5-Template-Tag no supported). All tests are based on JQuery 3.7.
106+
In the future we will probably remove the usage of JQuery in TKO, as many features have already been migrated to native APIs. Compatibility with JQuery in an application will remain.
107+
You can set useOnlyNativeEvents to false, so JQuery is also use for event-registration. Note: Some tests fails in this case ('change'-event doesn't fire). You can set useTemplateTag to false, so disable using HTML5-Template-Tags.
108+
103109
## Overview of the development stack
104110

105111
- **make** -> Build tasks

packages/bind/src/applyBindings.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,6 @@ export function applyBindingsToDescendants<T = any>(viewModelOrBindingContext: T
414414

415415
export function applyBindings<T = any>(viewModelOrBindingContext: BindingContext<T> | Observable<T> | T, rootNode: HTMLElement, extendContextCallback?: BindingContextExtendCallback<T>): Promise<unknown> {
416416
const asyncBindingsApplied = new Set()
417-
// If jQuery is loaded after Knockout, we won't initially have access to it. So save it here.
418-
if (options.jQuery === undefined && (globalThis as any).jQuery) {
419-
options.jQuery = (globalThis as any).jQuery
420-
}
421417

422418
// rootNode is optional
423419
if (!rootNode) {

packages/binding.core/src/style.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import {
77
unwrap
88
} from '@tko/observable'
99

10-
const {jQuery} = options
11-
1210
export var style = {
1311
update: function (element, valueAccessor) {
1412
var value = unwrap(valueAccessor() || {})
@@ -20,7 +18,7 @@ export var style = {
2018
styleValue = ''
2119
}
2220

23-
if (jQuery) {
21+
if (options.jQuery) {
2422
jQuery(element).css(styleName, styleValue)
2523
} else {
2624
styleName = styleName.replace(/-(\w)/g, (all, letter) => letter.toUpperCase())

packages/binding.if/spec/withBehaviors.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ describe('Binding: With', function () {
169169
})
170170

171171
it('Should be able to access all parent bindings when using "as"', async function () {
172+
173+
if(options.createChildContextWithAs) {
174+
console.log('Skip with-as because createChildContextWithAs is enabled')
175+
return;
176+
}
177+
172178
testNode.innerHTML = `<div data-bind='with: topItem'>
173179
<div data-bind="with: middleItem, as: 'middle'">
174180
<div data-bind='with: middle.bottomItem'>
@@ -205,6 +211,12 @@ describe('Binding: With', function () {
205211
})
206212

207213
it('Should not create a child context', function () {
214+
215+
if(options.createChildContextWithAs) {
216+
console.log('Skip with-as because createChildContextWithAs is enabled')
217+
return;
218+
}
219+
208220
testNode.innerHTML = "<div data-bind='with: someItem, as: \"item\"'><span data-bind='text: item.childProp'></span></div>"
209221
var someItem = { childProp: 'Hello' }
210222
applyBindings({ someItem: someItem }, testNode)
@@ -214,6 +226,12 @@ describe('Binding: With', function () {
214226
})
215227

216228
it('Should provide access to observable value', function () {
229+
230+
if(options.createChildContextWithAs) {
231+
console.log('Skip with-as because createChildContextWithAs is enabled')
232+
return;
233+
}
234+
217235
testNode.innerHTML = "<div data-bind='with: someItem, as: \"item\"'><input data-bind='value: item'/></div>"
218236
var someItem = observable('Hello')
219237
applyBindings({ someItem: someItem }, testNode)
@@ -232,6 +250,12 @@ describe('Binding: With', function () {
232250
})
233251

234252
it('Should not re-render the nodes when an observable value changes', function () {
253+
254+
if(options.createChildContextWithAs) {
255+
console.log('Skip with-as because createChildContextWithAs is enabled')
256+
return;
257+
}
258+
235259
testNode.innerHTML = "<div data-bind='with: someItem, as: \"item\"'><span data-bind='text: item'></span></div>"
236260
var someItem = observable('first')
237261
applyBindings({ someItem }, testNode)
@@ -244,6 +268,12 @@ describe('Binding: With', function () {
244268
})
245269

246270
it('Should remove nodes with an observable value become falsy', function () {
271+
272+
if(options.createChildContextWithAs) {
273+
console.log('Skip with-as because createChildContextWithAs is enabled')
274+
return;
275+
}
276+
247277
var someItem = observable(undefined)
248278
testNode.innerHTML = "<div data-bind='with: someItem, as: \"item\"'><span data-bind='text: item().occasionallyExistentChildProp'></span></div>"
249279
applyBindings({ someItem: someItem }, testNode)

packages/binding.template/spec/foreachBehaviors.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,12 @@ describe('Binding: Foreach', function () {
746746
*/
747747

748748
it('Should not create a child context when `as` is used', function () {
749+
750+
if(options.createChildContextWithAs) {
751+
console.log('Skip "as-item-usage" because createChildContextWithAs is enabled')
752+
return;
753+
}
754+
749755
testNode.innerHTML = "<div data-bind='foreach: { data: someItems, as: \"item\" }'><span data-bind='text: item'></span></div>"
750756
var someItems = ['alpha', 'beta']
751757
applyBindings({ someItems: someItems }, testNode)
@@ -758,6 +764,12 @@ describe('Binding: Foreach', function () {
758764
})
759765

760766
it('Should provide access to observable items', function () {
767+
768+
if(options.createChildContextWithAs) {
769+
console.log('Skip "as-item-usage" because createChildContextWithAs is enabled')
770+
return;
771+
}
772+
761773
testNode.innerHTML = "<div data-bind='foreach: { data: someItems, as: \"item\" }'><input data-bind='value: item'/></div>"
762774
var x = observable('first'), y = observable('second'), someItems = observableArray([ x, y ])
763775
applyBindings({ someItems: someItems }, testNode)

packages/provider.mustache/spec/textInterpolationSpec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ describe('Interpolation Markup bindings', function () {
279279
});
280280

281281
describe('Using unescaped HTML syntax', function () {
282+
283+
//jQuery-Templates (jquery.html(..)) doesn't works with mustache-templates
284+
if(!options.useTemplateTag && options.jQuery) {
285+
console.log('Skip some mustache-tests in combination with jquery-template')
286+
return;
287+
}
288+
282289
it('Should replace {{{...}}} expression with virtual html binding', function () {
283290
jasmine.setNodeText(testNode, "hello {{{'<b>name</b>'}}}!");
284291
applyBindings(null, testNode);
@@ -328,6 +335,12 @@ describe('Interpolation Markup bindings', function () {
328335

329336
describe('Using block syntax', function () {
330337
it('Should support "with"', function () {
338+
//jQuery-Templates (jquery.html(..)) doesn't works with mustache-templates
339+
if(!options.useTemplateTag && options.jQuery) {
340+
console.log('Skip some mustache-tests in combination with jquery-template')
341+
return;
342+
}
343+
331344
testNode.innerHTML = '<div><h1>{{title}}</h1>{{#with: story}}<div>{{{intro}}}</div><div>{{{body}}}</div>{{/with}}</div>';
332345
applyBindings({
333346
title: 'First Post',

packages/utils.parser/src/operators.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const operators:Operators = {
5252
'>=': function ge (a, b) { return a >= b },
5353
// TODO: 'in': function (a, b) { return a in b; },
5454
// TODO: 'instanceof': function (a, b) { return a instanceof b; },
55+
// TODO: 'typeof': function (a, b) { return typeof b; },
5556
// equality
5657
'==': function equal (a, b) { return a == b },
5758
'!=': function ne (a, b) { return a != b },

packages/utils/helpers/jasmine-13-helper.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
/// <reference types="jasmine" />
22
/// <reference types="jquery" />
33

4+
import jQuery from "jquery";
5+
window.jQuery = jQuery;
46

57
/*
68
* Configure the Jasmine testing framework.
79
*/
810
/* globals runs, waitsFor, jasmine */
911

1012
import {
11-
arrayMap, arrayFilter, ieVersion, selectExtensions, hasOwnProperty
13+
arrayMap, arrayFilter, ieVersion, selectExtensions, hasOwnProperty, options
1214
} from '../dist/'
1315

1416
window.DEBUG = true;
@@ -232,4 +234,21 @@ jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMil
232234

233235
beforeEach(function() {
234236
this.addMatchers(matchers);
237+
238+
switchJQueryState();
235239
});
240+
241+
afterEach(function() {
242+
expect(disableJQueryUsage).toEqual(options.disableJQueryUsage);
243+
})
244+
245+
const KARMA_STRING = '__karma__'
246+
var disableJQueryUsage = true;
247+
function switchJQueryState() {
248+
if (window[KARMA_STRING] && window[KARMA_STRING].config.args.includes('--noJQuery')) {
249+
options.disableJQueryUsage = disableJQueryUsage = true;
250+
} else {
251+
options.disableJQueryUsage = disableJQueryUsage = false;
252+
}
253+
}
254+

0 commit comments

Comments
 (0)