Skip to content

Commit 955e10d

Browse files
authored
Merge pull request #361 from canjs/major
Merge major branch for 6.0 release
2 parents 571a719 + e525c00 commit 955e10d

13 files changed

+216
-120
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: node_js
22
node_js: node
33
addons:
4-
firefox: '57.0'
4+
firefox: latest
55
dist: xenial
66
services:
77
- xvfb

can-component.js

Lines changed: 61 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
"use strict";
2-
/* jshint -W079 */
32

43
// # can-component.js
54
// This implements the `Component` which allows you to create widgets
@@ -17,7 +16,6 @@ var stache = require("can-stache");
1716
var stacheBindings = require("can-stache-bindings");
1817
var Scope = require("can-view-scope");
1918
var viewCallbacks = require("can-view-callbacks");
20-
var nodeLists = require("can-view-nodelist");
2119
var canReflect = require("can-reflect");
2220
var SimpleObservable = require("can-simple-observable");
2321
var SimpleMap = require("can-simple-map");
@@ -28,7 +26,6 @@ var assign = require('can-assign');
2826
var ObservationRecorder = require("can-observation-recorder");
2927
var queues = require("can-queues");
3028
var domData = require('can-dom-data');
31-
var getChildNodes = require('can-child-nodes');
3229
var string = require("can-string");
3330
var domEvents = require('can-dom-events');
3431
var domMutate = require('can-dom-mutate');
@@ -57,7 +54,7 @@ var viewModelSymbol = canSymbol.for('can.viewModel');
5754

5855

5956
// ## Helpers
60-
var noop = function(){};
57+
6158
// ### addContext
6259
// For replacement elements like `<can-slot>` and `<context>`, this is used to
6360
// figure out what data they should render with. Slots can have bindings like
@@ -176,19 +173,31 @@ function makeReplacementTagCallback(tagName, componentTagData, shadowTagData, le
176173
// Now we need to render the right template and insert its result in the page.
177174
// We need to teardown any bindings created too so we create a nodeList
178175
// to do this.
176+
var fragment = template(tagData.scope, tagData.options);
177+
if(tagData.teardown) {
179178

179+
var placeholder = el.ownerDocument.createComment(tagName);
180+
fragment.insertBefore(placeholder, fragment.firstChild);
181+
domMutate.onNodeRemoved(placeholder, tagData.teardown);
182+
}
180183

181-
184+
el.parentNode.replaceChild(
185+
fragment,
186+
el
187+
);
188+
/*
182189
var nodeList = nodeLists.register([el], tagData.teardown || noop,
183190
insertionElementTagData.parentNodeList || true,
184191
insertionElementTagData.directlyNested);
185192
186193
nodeList.expression = "<can-slot name='"+el.getAttribute('name')+"'/>";
187194
188-
var frag = template(tagData.scope, tagData.options, nodeList);
195+
var frag = template(tagData.scope, tagData.options);
196+
197+
189198
var newNodes = canReflect.toArray( getChildNodes(frag) );
190199
var oldNodes = nodeLists.update(nodeList, newNodes);
191-
nodeLists.replace(oldNodes, frag);
200+
nodeLists.replace(oldNodes, frag);*/
192201

193202
// Restore the proper tag function so it could potentially be used again (as in lists)
194203
options.tags[tagName] = replacementTag;
@@ -236,7 +245,8 @@ function getSetupFunctionForComponentVM(componentInitVM) {
236245
var canBinding = new Bind({
237246
child: child,
238247
parent: parent,
239-
queue: "domUI",
248+
queue: "dom",
249+
element: el,
240250

241251
//!steal-remove-start
242252
// For debugging: the names that will be assigned to the updateChild
@@ -539,13 +549,30 @@ var Component = Construct.extend(
539549
el.viewModel = viewModel;
540550
domData.set(el, "preventDataBindings", true);
541551

542-
// an array of teardown stuff that should happen when the element is removed
543-
var teardownFunctions = [];
544-
var callTeardownFunctions = function() {
545-
for (var i = 0, len = teardownFunctions.length; i < len; i++) {
546-
teardownFunctions[i]();
547-
}
548-
};
552+
// TEARDOWN SETUP
553+
var removedDisposal,
554+
connectedDisposal,
555+
viewModelDisconnectedCallback;
556+
function teardownComponent(){
557+
if(removedDisposal) {
558+
removedDisposal();
559+
removedDisposal = null;
560+
}
561+
component._torndown = true;
562+
domEvents.dispatch(el, "beforeremove", false);
563+
if(teardownBindings) {
564+
teardownBindings();
565+
}
566+
if(viewModelDisconnectedCallback) {
567+
viewModelDisconnectedCallback(el);
568+
} else if(typeof viewModel.stopListening === "function"){
569+
viewModel.stopListening();
570+
}
571+
if(connectedDisposal) {
572+
connectedDisposal();
573+
connectedDisposal = null;
574+
}
575+
}
549576

550577
// #### Helpers
551578
// TODO: remove in next release
@@ -558,33 +585,25 @@ var Component = Construct.extend(
558585
});
559586
}
560587

561-
562588
// #### `events` control
563589
// TODO: remove in next release
564590
// Create a control to listen to events
565591
if(this.constructor.Control) {
566592
this._control = new this.constructor.Control(el, {
567593
// Pass the viewModel to the control so we can listen to it's changes from the controller.
568594
scope: this.viewModel,
569-
viewModel: this.viewModel,
570-
destroy: callTeardownFunctions
571-
});
572-
} else {
573-
var removalDisposal = domMutate.onNodeRemoval(el, function () {
574-
var doc = el.ownerDocument;
575-
var rootNode = doc.contains ? doc : doc.documentElement;
576-
if (!rootNode || !rootNode.contains(el)) {
577-
if(removalDisposal) {
578-
nodeRemoved = true;
579-
removalDisposal();
580-
callTeardownFunctions();
581-
removalDisposal = null;
582-
callTeardownFunctions = null;
583-
}
584-
}
595+
viewModel: this.viewModel
585596
});
586597
}
587598

599+
removedDisposal = domMutate.onNodeRemoved(el, function () {
600+
var doc = el.ownerDocument;
601+
var rootNode = doc.contains ? doc : doc.documentElement;
602+
if (!rootNode || !rootNode.contains(el)) {
603+
teardownComponent();
604+
}
605+
});
606+
588607
// #### Rendering
589608

590609
var leakScope = {
@@ -644,61 +663,32 @@ var Component = Construct.extend(
644663
betweenTagsTagData = lightTemplateTagData;
645664
betweenTagsView = componentTagData.subtemplate || el.ownerDocument.createDocumentFragment.bind(el.ownerDocument);
646665
}
647-
var viewModelDisconnectedCallback,
648-
insertionDisposal,
649-
componentInPage,
650-
nodeRemoved;
666+
667+
668+
651669

652670
// Keep a nodeList so we can kill any directly nested nodeLists within this component
653-
var nodeList = nodeLists.register([], function() {
654-
if(removalDisposal && !nodeRemoved) {
655-
removalDisposal();
656-
callTeardownFunctions();
657-
removalDisposal = null;
658-
callTeardownFunctions = null;
659-
}
660-
component._torndown = true;
661-
domEvents.dispatch(el, "beforeremove", false);
662-
if(teardownBindings) {
663-
teardownBindings();
664-
}
665-
if(viewModelDisconnectedCallback) {
666-
viewModelDisconnectedCallback(el);
667-
} else if(typeof viewModel.stopListening === "function"){
668-
viewModel.stopListening();
669-
}
670-
if(insertionDisposal) {
671-
insertionDisposal();
672-
insertionDisposal = null;
673-
}
674-
}, componentTagData.parentNodeList || true, false);
675-
nodeList.expression = "<" + this.tag + ">";
676-
teardownFunctions.push(function() {
677-
nodeLists.unregister(nodeList);
678-
});
679-
this.nodeList = nodeList;
680671

681-
shadowFragment = betweenTagsView(betweenTagsTagData.scope, betweenTagsTagData.options, nodeList);
672+
673+
674+
shadowFragment = betweenTagsView(betweenTagsTagData.scope, betweenTagsTagData.options);
682675

683676
// TODO: afterRender
684677

685678
// Append the resulting document fragment to the element
686679
domMutateNode.appendChild.call(el, shadowFragment);
687680

688-
// update the nodeList with the new children so the mapping gets applied
689-
nodeLists.update(nodeList, getChildNodes(el));
690-
691681
// Call connectedCallback
692682
if(viewModel && viewModel.connectedCallback) {
693683
var body = DOCUMENT().body;
694-
componentInPage = body && body.contains(el);
684+
var componentInPage = body && body.contains(el);
695685

696686
if(componentInPage) {
697687
viewModelDisconnectedCallback = viewModel.connectedCallback(el);
698688
} else {
699-
insertionDisposal = domMutate.onNodeInsertion(el, function () {
700-
insertionDisposal();
701-
insertionDisposal = null;
689+
connectedDisposal = domMutate.onNodeConnected(el, function () {
690+
connectedDisposal();
691+
connectedDisposal = null;
702692
viewModelDisconnectedCallback = viewModel.connectedCallback(el);
703693
});
704694
}
@@ -713,7 +703,6 @@ Component.prototype[viewInsertSymbol] = function(viewData) {
713703
if(this._torndown) {
714704
this.setup.apply(this,this._initialArgs);
715705
}
716-
viewData.nodeList.newDeepChildren.push(this.nodeList);
717706
return this.element;
718707
};
719708

control/control.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ var ComponentControl = Control.extend({
6161
this._bindings.readyComputes = {};
6262
},
6363
destroy: function() {
64-
Control.prototype.destroy.apply(this, arguments);
6564
if (typeof this.options.destroy === 'function') {
6665
this.options.destroy.apply(this, arguments);
6766
}
67+
Control.prototype.destroy.apply(this, arguments);
68+
6869
}
6970
});
7071

docs/component.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
@download can/component
33
@test can/component/test.html
44
@parent can-views
5-
@collection can-core
5+
@collection can-legacy
66
@release 2.0
77
@link ../docco/component/component.html docco
88
@group can-component.define 0 define

package.json

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "can-component",
3-
"version": "4.6.3",
3+
"version": "5.0.0-pre.5",
44
"description": "Custom elements for CanJS",
55
"homepage": "https://canjs.com/doc/can-component.html",
66
"repository": {
@@ -40,44 +40,45 @@
4040
},
4141
"dependencies": {
4242
"can-assign": "^1.1.1",
43-
"can-bind": "^1.4.0",
43+
"can-bind": "^1.5.0",
4444
"can-child-nodes": "^1.0.0",
4545
"can-construct": "^3.2.0",
46-
"can-control": "^4.0.0",
46+
"can-control": "^5.0.0-pre.0",
4747
"can-define": "^2.0.0",
4848
"can-dom-data": "^1.0.1",
4949
"can-dom-events": "^1.1.0",
50-
"can-dom-mutate": "^1.0.0",
50+
"can-dom-mutate": "^2.0.0",
5151
"can-fragment": "^1.0.0",
5252
"can-globals": "^1.0.0",
5353
"can-log": "^1.0.0",
5454
"can-namespace": "1.0.0",
5555
"can-observation": "^4.0.0",
5656
"can-observation-recorder": "^1.2.0",
57-
"can-queues": "^1.0.0",
57+
"can-queues": "^1.3.0",
5858
"can-reflect": "^1.6.0",
5959
"can-simple-map": "^4.1.0",
6060
"can-simple-observable": "^2.0.0",
61-
"can-stache": "^4.10.0",
62-
"can-stache-bindings": "^4.9.0",
61+
"can-stache": "^5.0.0-pre.3",
62+
"can-stache-bindings": "^5.0.0-pre.3",
6363
"can-stache-key": "^1.0.0",
6464
"can-string": "<2.0.0",
6565
"can-symbol": "^1.4.1",
66-
"can-view-callbacks": "^4.2.0",
66+
"can-view-callbacks": "^5.0.0-pre.1",
6767
"can-view-model": "^4.0.0",
68-
"can-view-nodelist": "^4.1.0",
6968
"can-view-scope": "^4.7.0"
7069
},
7170
"devDependencies": {
71+
"can-diff": "^1.5.0",
7272
"can-observe": "^2.0.0",
7373
"can-test-helpers": "^1.1.2",
7474
"can-value": "<2.0.0",
7575
"can-vdom": "^4.0.0",
76+
"can-simple-dom": "^1.7.0",
7677
"detect-cyclic-packages": "^1.1.0",
7778
"docco": "^0.8.0",
78-
"highlight.js": "^9.15.7",
7979
"done-serve": "^2.0.0",
8080
"gh-pages": "^2.0.1",
81+
"highlight.js": "^9.15.7",
8182
"jshint": "^2.9.1",
8283
"steal": "^1.0.0",
8384
"steal-qunit": "^2.0.0",

test/component-can-bind-test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var helpers = require("./helpers");
44
var QUnit = require("steal-qunit");
55
var SimpleMap = require("can-simple-map");
66
var value = require("can-value");
7+
var domMutateNode = require("can-dom-mutate/node/node");
78
var queues = require("can-queues");
89
var testHelpers = require("can-test-helpers");
910

@@ -52,7 +53,7 @@ QUnit.test("Using can-bind in connectedCallback works as documented", function(a
5253

5354
// Insert the component into the page; connectedCallback will run
5455
var fixture = document.getElementById("qunit-fixture");
55-
fixture.appendChild(element);
56+
domMutateNode.appendChild.call(fixture, element);
5657
helpers.afterMutation(function() {
5758

5859
// Because this is a one-way parent-to-child binding, the child will be set

test/component-events-test.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ helpers.makeTests("can-component events", function(){
9898
});
9999

100100
var renderer = stache("<can-parent-stache></can-parent-stache>");
101-
102-
domMutateNode.appendChild.call(this.fixture, renderer());
101+
var frag = renderer();
102+
domMutateNode.appendChild.call(this.fixture, frag);
103103
var done = assert.async();
104104
setTimeout(function () {
105105
undo();
@@ -147,7 +147,7 @@ helpers.makeTests("can-component events", function(){
147147
HANDLER.call(Test,{type:"something"});
148148
});
149149

150-
QUnit.test('removing bound viewModel properties on destroy #1415', function(assert) {
150+
QUnit.test('removing bound viewModel properties on connectedCallback #1415', function(assert) {
151151
var state = new SimpleMap({
152152
product: new SimpleMap({
153153
id: 1,
@@ -157,9 +157,9 @@ helpers.makeTests("can-component events", function(){
157157

158158
Component.extend({
159159
tag: 'destroyable-component',
160-
events: {
161-
destroy: function(){
162-
this.viewModel.set("product" , null);
160+
ViewModel: {
161+
connectedCallback: function(){
162+
this.set("product" , null);
163163
}
164164
}
165165
});
@@ -249,7 +249,7 @@ helpers.makeTests("can-component events", function(){
249249
undo();
250250
}], done);
251251

252-
252+
253253

254254
});
255255

0 commit comments

Comments
 (0)