Releases: canjs/canjs
preventing $.event.add and $.event.remove when bind/unbind are called on Document Fragments
Repo & website updates
This release fixed some things in the repo and on the website.
Diff: v3.10.2...v3.10.3
Fixing binding to getters that use `lastSetVal`
can-define@1.4.5 - Fixing binding to getters that use lastSetVal
This fixes an issue where if you have a getter using lastSetVal
like:
place: {
get: function(lastSet){
if(lastSet) {
return lastSet;
}
}
}
and were binding to it in a template like:
{{#if place}}
THERE IS A PLACE
{{/if}}
The template would not be updated when setting place
.
can-reflect-promise@1.1.1 - moved docs to can-infrastructure
Helpful Warnings and Fix for `parent.replacements` Issue
Notable Bug Fixes / Docs
can-define@1.4.4 - Helpful warnings
Warn when setting a property that has only a zero-arg getter
var VM = DefineMap.extend({
derivedProp: {
get: function() {
return "Hello World";
}
}
});
var vm = new VM();
vm.derivedProp = 'prop is set';
can-define: Set value for property derivedProp ignored, as its definition has a zero-argument getter and no setter
Warn when value property is assigned an object
DefineMap.extend({
options: {
value: {
foo: 'bar',
abc: 'xyz'
}
}
});
can-define: The value for options is set to an object. This will be shared by all instances of the DefineMap. Use a function that returns the object instead.
Warn when value property is assigned a constructor
DefineMap.extend({
options: {
value: DefineMap
}
});
can-define: The "value" for options is set to a constructor. Did you mean "Value" instead?
Warn when a constructor is supplied as a type definition
var VM = DefineMap.extend({
currency: {
type: Currency
}
});
can-define: the definition for currency uses a constructor for "type". Did you mean "Type"?
can-component@3.3.4 - warns if viewModel is assigned a DefineMap
A warning will be shown if a constuctor is passed as the viewModel
property (with a lower-case v
) of a can-component
since ViewModel
should be used:
var VM = DefineMap.extend({});
Component.extend({
tag: 'can-vm1-test-component',
viewModel: VM
});
can-component: Assigning a DefineMap or constructor type to the viewModel property may not be what you intended. Did you mean ViewModel instead? More info: https://canjs.com/doc/can-component.prototype.ViewModel.html
can-route@3.2.3 - Remove extra warnings
This removes warnings when two routes match, but one has a trailing /
:
WARN: two routes were registered with matching keys:
(1) route("internet", {"page":"internet"})
(2) route("internet/", {"page":"internet"})
(1) will always be chosen since it was registered first
can-view-live@3.2.3 - running add,set,remove,move in the Observation update queue
This fixes an issue where parent.replacements
was null at times in the register
function in cases where an {{#if ...}}
surrounded an {{#each ...}}
and the list was modified in the same batch as the if
was toggled to remove the each
:
{{#if show}}
{{#each items as item}}
{{item}}
{{/each}}
{{/if}}
show = false;
list.replace([ 'two', 'three' ]);
Other Bug Fixes
- Remove pre-release package references - can-compute@3.3.4, can-connect-cloneable@0.2.1, can-connect-signalr@0.2.2, can-construct@3.2.1, can-construct-super@3.1.2, can-ejs@3.1.5, can-fixture@1.1.1,
can-fixture-socket@0.7.1, can-list@3.2.1, can-map@3.3.4, can-route@3.2.2, can-simple-map@3.3.1, can-stache-converters@3.2.2, can-util@3.9.10, can-view-live@v3.2.2 - can-ejs@3.1.6
- can-element@0.2.1 - Fixes broken build due to cloudydom@1.0.7 breaking issue
v3.10.0
New Features
New Bindings Syntax
can-stache-bindings has intuitive new syntaxes for event, one-way bindings, and two-way bindings:
on:event="key()"
for event binding.prop:from="key"
for one-way parent-to-child binding.prop:to="key"
for one-way child-to-parent binding.prop:bind="key"
for two-way binding.
To upgrade to the new binding syntaxes, try out the codemod in can-migrate.
Named inline partials
You can now define reusable partials inside your templates!
In the example below, addressTemplate
is defined as a partial and then used later in the same template:
Learn more in the {{<partialName}} docs.
{{debugger}
In development, the new {{debugger}}
stache helper will break at the given point in the template so you can inspect the current scope in the browser’s console.
Learn more in the {{debugger}} docs.
Control whitespace in stache templates
Sometimes it’s useful to prevent stache from rendering whitespace, such as when you want to target an element with the :empty CSS selector.
If you add -
to your magic tags, you can have this:
<div>
{{-#if user.isMarried-}}
Mrs
{{-else-}}
Miss
{{-/if-}}
</div>
…rendered as this:
<div>{{#if user.isMarried}}Mrs{{else}}Miss{{/if}}</div>
Learn more in the Whitespace Control docs.
Complete list of minor updates
can-define@1.4.0 - Observable indexed value changes
can-event@3.7.0 - RemoveEventListener can now remove all events and IE9 bug fixes
can-stache@3.3.0 - Whitespace Control
can-stache@3.4.0 - Updating can-view-parser to support new binding syntaxes
can-stache@3.5.0 - Added debugger helper
can-stache@3.6.0 - Adding inline Named Partials functionality
can-stache-bindings@3.5.0 - New colon binding syntaxes
can-stache-bindings@3.6.0 - on:vm:event and on:el:event
can-stache-bindings@3.7.0 - Specify events for data bindings, other fixes
can-vdom@3.2.0 - Adds the Node
type to the exported globals in make-window
can-view-parser@3.5.0 - Using can-attribute-encoder for encoding attributes
New Packages
can-attribute-encoder
Encode and decode strings to be used as attribute names in the DOM:
var encodedAttributeName = encoder.encode("{(^$foo/bar baz)}");
encoder.decode(attributeName); // -> "{(^$foo/bar baz)}"
can-element
Create customelement classes with CanJS.
var Element = require("can-element").Element;
var stache = require("can-stache");
var define = require("can-define");
var view = stache("Hello {{name}}");
var MyApp = class extends Element {
static get view() {
return view;
}
};
define(MyApp.prototype, {
name: {
value: "world"
}
});
customElements.define("my-app", MyApp);
var el = document.createElement("my-app");
el.name; // -> "world"
can-kefir
Integrate KefirJS streams directly within can-stache and other parts of CanJS.
var Kefir = require("can-kefir");
var countTo3Stream = Kefir.sequentially(1000,[1,2,3]);
var view = stache("<p>Number: {{countTo3Stream.value}}</p>");
var frag = view({
countTo3Stream: countTo3Stream
});
document.body.appendChild(frag);
can-observe
Create observable objects that acts as a proxy for target objects.
var dog = observe({});
dog.addEventListener('name', function(){
// Name changed!
});
dog.name = 'Wilbur';
Bug Fixes, Documentation Improvements
can-component@3.3.1 - https://github.com/canjs/can-component/releases/tag/v3.3.1
can-component@3.3.2 - Updating can-stache-key to receive bug fixes
can-component@3.3.3 - removed can-* pre-releases3
can-compute@3.3.2 - Updating can-stache-key
can-compute@3.3.3 - Use typeof to check for console & Update can-stache-key
can-connect@1.5.7 - Replaced console
with canLog
can-connect@1.5.8 - Removing deprecated can-types method
can-connect-feathers@3.6.1
can-connect-feathers@3.6.2
can-control@3.2.1 - Updating can-stache-key
can-control@3.2.2 - Updating can-stache-key to receive bug fixes
can-define@1.4.1
can-define@1.4.2 - Calling define adds a CID
can-define@1.4.3
can-ejs@3.1.3 - Updating can-stache-key
can-ejs@3.1.4 - Updating can-stache-key to receive bug fixes
can-event@3.6.2 - Handle Console Not Being Present
can-event@3.7.1 - can-event/batch/batch logs a warning on missing stop
can-map@3.3.2 - Updating can-stache-key
can-map@3.3.3 - Updating can-stache-key to receive bug fixes
can-observation@3.3.3 - Use canLog
Instead of console
can-observation@3.3.4 - deprecated
can-observation@3.3.5
can-stache@3.3.1 - Warn when can-stache-bindings is not imported
can-stache@3.3.2 - Plain js objects now work with subtemplate
can-stache@3.3.3 - Fixed Test for can-jquery
can-stache@3.3.4 - Updating can-stache-key
can-stache@3.5.1 - Fixing issue with debugger helper in production
can-stache@3.5.2 - Updating can-stache-key to receive bug fixes
can-stache@3.6.1 - Warning when using on:, :to, :from, :bind and not importing can-stache-bindings
can-stache@3.6.2 - Doc update: warnings on recursive named partials
can-stache-bindings@3.4.5 - Docs and Deps
can-stache-bindings@3.4.6 - Improved warnings
can-stache-bindings@3.4.7 - Updating can-stache-key
can-stache-bindings@3.6.1 - Updating can-stache-key to receive bug fixes
can-stache-bindings@3.6.2 - encoding attribute before looking for callback
can-stache-bindings@3.6.3 - Fixed endsWith in IE
can-stache-key@0.1.0 - minor version bump to allow dependent packages to receive bug fixes
can-util@3.9.9 - Change async tests to polling
can-view-autorender@3.1.1 - Updated dependencies
[can-view-scope@3.3.3 - Updating can-stache-ke...
v3.9.1
- can-connect@1.5.4 - Documentation Improvements
- can-connect@1.5.5 - Fix IE Compatibility
- can-connect@1.5.6 - Removed console.log statement
- can-connect-signalr@0.2.1 - Removing console.log
- can-construct-super@3.1.1 - Removing console.log
- can-define@1.3.3 - removing use of deprecated isString / isArray functions
- can-define-stream-kefir@0.1.2 - Removed console.log statement
- can-event@3.6.1 - fix issue with debounce removing all batchEnd events
- can-ndjson-stream@0.1.5 - Add build script
- can-ndjson-stream@0.1.6 - Include dependencies in the global build
- can-observation@3.3.2 - making it possible to rebind observations
- can-react-component@0.1.7 - Save can-namespace in package.json dependencies
- can-reflect@1.2.4 - Reflexed Tooling
- can-reflect@1.2.5 - Handle decorated and builtIn types correctly
- can-reflect@1.2.6 - Added checks for Map/Set in unsupported browsers
- can-route@3.2.1 - fixing issue with can-maps in SSR
- can-set@1.3.2 - Ignore pagination in set.has
- can-simple-dom@1.1.0 - adds
<head>
element to newly created documents - can-simple-dom@1.1.1 - Fixes issue with the ownerDocument not being updated when moving nodes from one document into another
- can-simple-dom@1.2.0 - Add no-op CSSStyleDeclaration.getPropertyValue method
- can-stache-converters@3.2.1 - either-or helper handles case where neither a or b match ~chosen
- can-stache-key@0.0.4 - return null when promise getter returns null
- can-types@1.1.1 - Direct Utility
- can-util@3.9.7 - attr.set supports attributes with namespaces
- can-util@3.9.8 - Deprecated is-string and is-array
- can-vdom@3.1.1 - Upgrade can-simple-dom
- can-view-live@3.2.1 - The Way You Move
- can-view-scope@3.3.1 - restoring dependencyChange/start on offValue
- can-view-scope@3.3.2 - Add references scope if none for
getRefs
- can-view-target@3.1.1 - Keeps non-default element namespace
v2.3.32
can-reflect, react-view-model, ndjson streams, slots
Big Changes
can-reflect and can-symbol
can-reflect and can-symbol - Created a unified interface for all observable CanJS types. For example, to set a name
property on a can.Map
, DefineMap
, or SimpleMap
, you can now use:
canReflect.setKeyValue(map,"name", "my map");
This let us use the much faster can-observation throughout CanJS's codebase, resulting in improved application initialization performance times, especially if you are using Call Expressions which can keep everything as an Observation.
React View Model
If you are using React
, but like the clarity and ease of CanJS's DefineMap ViewModels, you are in luck. react-view-model lets you create react components that use DefineMap
as a nicely unit-testable ViewModel. No more calling setState
. Instead just change a property on your ViewModel.
The following creates a React CounterComponent
with a CounterViewModel
:
var CounterViewModel = DefineMap.extend({
count: 'number',
increment: function() {
return this.count++;
},
});
var CounterComponent = reactViewModel("CounterComponent", CounterViewModel, (counterVM) => {
return (
<div onClick={ counterVM.increment.bind(counterVM) }>
Count: {counterVM.count} (Click Me)
</div>
);
});
NDJSON streams
Apparently 2016 was the year of streams. I disagree, it's going to be 2018 as only Google Chrome and Safari support fetch
and ReadableStream
. However, what a year 2018 will be! I'll try to explain:
fetch
is the new, much more powerful, XMLHTTPRequest object. It lets you do "AJAX".- It's also going to let you access a streaming response body through ReadableStream interface.
- NDJSON is a format that streams JSON.
Combining these ideas, it's possible to stream out a database response (or even cached data) in NDJSON and have the page display information as soon as it gets it:
EPIC PERFORMANCE WIN!
We created two modules to help use streams:
- can-ndjson-stream - Use to access the raw response stream of
fetch
and convert it to a stream of JavaScript objects. - can-connect-ndjson - Stream an NDJSON response into a
DefineList
.
Component slots
The Web Components <slot>
and <template>
specifications promise to make customizing native custom elements easy. Until that glorious day happens, we've added our own <can-slot>
and <can-template>
.
Let’s say we’re creating a modal component that we want to make customizable by passing in templates for its header, body, and footer:
Component.extend({
tag: 'ui-modal',
view: stache(`
<div class="modal">
<div class="modal-content">
<div class="modal-header">
<can-slot name="header" />
</div>
<div class="modal-body">
<can-slot name="body" />
</div>
<div class="modal-footer">
<can-slot name="footer" />
</div>
</div>
</div>
`)
});
In the component’s template, we’re providing the structure around the header, body, and footer. Then, we use can-slot
to allow other components to specify what should be inserted into those sections.
Now let’s use our ui-modal
component:
const renderer = stache(`
<ui-modal>
<can-template name="header">
<h5 class="modal-title">{{titleText}}</h5>
</can-template>
<can-template name="body">
<p>{{bodyText}}</p>
</can-template>
<can-template name="footer">
<button type="button" class="btn btn-primary">{{primaryButtonText}}</button>
<button type="button" class="btn btn-secondary">{{secondaryButtonText}}</button>
</can-template>
</ui-modal>
`);
renderer({
titleText: 'Discard your changes?',
bodyText: 'Your data will not be saved.',
primaryButtonText: 'Discard',
secondaryButtonText: 'Cancel'
});
In the template, we’re using can-template
to specify what should be inserted into the can-slot
sections in our ui-modal
component. Then, we’re rendering that template with the object provided to renderer
.
The final HTML structure will look like this:
<ui-modal>
<div class="modal">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Discard your changes?</h5>
</div>
<div class="modal-body">
<p>Your data will not be saved.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Discard</button>
<button type="button" class="btn btn-secondary">Cancel</button>
</div>
</div>
</div>
</ui-modal>
Learn more in the <can-slot>
and <can-template>
documentation.
v3.8.2
- can-define@1.0.25 - Length Event Fixes
- can-define@1.0.26 - Remove use of steal-only import syntax
- can-fixture@1.0.14 - Mix of Fix
- can-observation@3.1.5 - Report Promise Errors
- can-route@3.0.11 - Fix decoding of unicode characters
- can-simple-map@3.1.4 - .serialize and .get are observable
- can-stache-bindings@3.1.5 - Event binding leak fix
- can-stache-converters@3.1.0 - Adds ability to use equal with more than two arguments