diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..caae816
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,85 @@
+# Contributing to can-define
+
+Check out the [contribution guide on CanJS.com](https://canjs.com/doc/guides/contribute.html) for information on:
+
+- [Code of Conduct](https://canjs.com/doc/guides/contribute.html#CodeofConduct)
+- [Getting Help](https://canjs.com/doc/guides/contribute.html#GettingHelp)
+- [Project Organization](https://canjs.com/doc/guides/contributing/project-organization.html)
+- [Reporting Bugs](https://canjs.com/doc/guides/contributing/bug-report.html)
+- [Suggesting Features](https://canjs.com/doc/guides/contributing/feature-suggestion.html)
+- [Finding Ways to Contribute](https://canjs.com/doc/guides/contributing/finding-ways-to-contribute.html)
+
+The rest of this guide has information that’s specific to this repository.
+
+## Developing Locally
+
+This section will walk you through setting up the [repository](https://github.com/canjs/can-define) on your computer.
+
+### Signing up for GitHub
+
+If you don’t already have a GitHub account, you’ll need to [create a new one](https://help.github.com/articles/signing-up-for-a-new-github-account/).
+
+### Forking & cloning the repository
+
+A “fork” is a copy of a repository in your personal GitHub account. “Cloning” is the process of getting the repository’s source code on your computer.
+
+GitHub has a guide for [forking a repo](https://help.github.com/articles/fork-a-repo/). To fork can-define, you can start by going to its [fork page](https://github.com/canjs/can-define/fork).
+
+Next, you’ll want to clone the repo. [GitHub’s cloning guide](https://help.github.com/articles/cloning-a-repository/) explains how to do this on Linux, Mac, or Windows.
+
+GitHub’s guide will [instruct you](https://help.github.com/articles/fork-a-repo/#step-2-create-a-local-clone-of-your-fork) to clone it with a command like:
+
+```shell
+git clone https://github.com/YOUR-USERNAME/can-define
+```
+
+Make sure you replace `YOUR-USERNAME` with your GitHub username.
+
+### Installing the dependencies
+
+After you’ve forked & cloned the repository, you’ll need to install the project’s dependencies.
+
+First, make sure you’ve [installed Node.js and npm](https://docs.npmjs.com/getting-started/installing-node).
+
+If you just cloned the repo from the command line, you’ll want to switch to the folder with your clone:
+
+```shell
+cd can-define
+```
+
+Next, install the project’s dependencies with npm:
+
+```shell
+npm install
+```
+
+### Starting the development server
+
+Run the following to start a dev server:
+
+```shell
+npm run develop
+```
+
+### Running the tests
+
+You can manually run this repository’s tests in any browser by starting the dev server (see the section above) and visiting this page: http://localhost:8080/test/test.html
+
+Firefox is used to run the repository’s automated tests from the command line. If you don’t already have it, [download Firefox](https://www.mozilla.org/en-US/firefox/new/). Mozilla has guides for installing it on [Linux](https://support.mozilla.org/t5/Install-and-Update/Install-Firefox-on-Linux/ta-p/2516), [Mac](https://support.mozilla.org/t5/Install-and-Update/How-to-download-and-install-Firefox-on-Mac/ta-p/3453), and [Windows](https://support.mozilla.org/t5/Install-and-Update/How-to-download-and-install-Firefox-on-Windows/ta-p/2210).
+
+After Firefox is installed, you can run:
+
+```shell
+npm test
+```
+
+### Making a build
+
+Run the following command to create a build:
+
+```shell
+npm run build
+```
+
+This will create a `dist/` folder that contains the AMD, CommonJS, and global module versions of the project.
+
diff --git a/README.md b/README.md
index f9b711e..0afd214 100644
--- a/README.md
+++ b/README.md
@@ -1,714 +1,26 @@
-[![Build Status](https://travis-ci.org/canjs/can-define.svg?branch=master)](https://travis-ci.org/canjs/can-define)
-
# can-define
+[![Join the chat at https://gitter.im/canjs/canjs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/canjs/canjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/canjs/can-define/blob/master/LICENSE)
+[![npm version](https://badge.fury.io/js/can-define.svg)](https://www.npmjs.com/package/can-define)
+[![Travis build status](https://travis-ci.org/canjs/can-define.svg?branch=master)](https://travis-ci.org/canjs/can-define)
[![Greenkeeper badge](https://badges.greenkeeper.io/canjs/can-define.svg)](https://greenkeeper.io/)
Add observable properties, type conversion, and getter/setter logic to your constructor prototypes.
-- [__can-define__ function](#can-define-function)
- - [can.define(prototype, propDefinitions)](#candefineprototype-propdefinitions)
- - [propDefinition Object](#propdefinition-object)
- - [types Object](#types-object)
-- [__can-define/map/map__ function](#can-definemapmap-function)
- - [new can.DefineMap([props])](#new-candefinemapprops)
- - _static_
- - [can.DefineMap.extend([name,] [static,] prototype)](#candefinemapextendname-static-prototype)
- - [seal Boolean](#seal-boolean)
- - _prototype_
- - [map.each( callback(item, propName ) )](#mapeach-callbackitem-propname--)
- - [map.toObject()](#maptoobject)
- - [map.serialize()](#mapserialize)
- - [map.get(propName)](#mapgetpropname)
- - [map.set(propName, value)](#mapsetpropname-value)
-- [__can-define/list/list__ function](#can-definelistlist-function)
- - [new can.DefineList([items])](#new-candefinelistitems)
- - _prototype_
- - [map.item(index, [newVal])](#mapitemindex-newval)
- - [map.items()](#mapitems)
- - [list.each( callback(item, index) )](#listeach-callbackitem-index-)
- - [list.forEach(callback[, thisArg])](#listforeachcallback-thisarg)
- - [list.splice(index[, howMany[, ...newElements]])](#listspliceindex-howmany-newelements)
- - [list.replace(collection)](#listreplacecollection)
- - [list.push(...elements)](#listpushelements)
- - [list.unshift(...elements)](#listunshiftelements)
- - [list.pop()](#listpop)
- - [list.shift()](#listshift)
- - [list.indexOf(item)](#listindexofitem)
- - [list.join(separator)](#listjoinseparator)
- - [list.reverse()](#listreverse)
- - [list.slice([start[, end]])](#listslicestart-end)
- - [list.concat(...args)](#listconcatargs)
-
-## API
-
-
-## __can-define__ function
-Exports the `can.define` method that defines observable properties and their behavior.
-
-
-
-### can.define(prototype, propDefinitions)
-
-
-Define observable properties, type conversion, and getter/setter logic to your constructor prototypes.
-
-```js
-var Person = function(first, last){
- this.first = first;
- this.last = last;
-};
-can.define(Person.prototype,{
- first: {
- type: "string"
- },
- last: {
- type: "string"
- },
- fullName: {
- get: function(){
- return this.first+" "+this.last;
- }
- }
-});
-```
-
-
-1. __prototype__ {Object}
:
- The prototype object of a constructor function.
-
-1. __propDefinitions__ {Object\}
:
- An object of
- properties and their definitions.
-
-#### propDefinition `{Object}`
-
-
-Defines the type, initial value, and get, set, and serialize behavior for an
-observable property.
-
-
-
-##### Object
-
-- __value__ {function|*}
:
- Specifies the initial value of the property or
- a function that returns the initial value.
-
- ```js
- // A default age of `0`:
- var Person = DefineMap.extend({
- age: {value: 0}
- });
-
- new Person().age //-> 0
- ```
-
- `Object` types should not be specified directly on `value` because that same object will
- be shared on every instance of the Map. Instead, a function that returns a fresh copy should be provided:
-
- ```js
- // A default address object:
- var Person = DefineMap.extend({
- address: {
- value: function(){
- return {city: "Chicago", state: "IL"};
- };
- }
- });
-
- new Person().address //-> {city: "Chicago", state: "IL"};
- ```
-
-- __Value__ {function}
:
- Specifies a function that will be called with `new` whose result is
- set as the initial value of the attribute.
-
- ```js
- // A default empty DefineList of hobbies:
- var Person = DefineMap.extend({
- hobbies: {Value: DefineList}
- });
-
- new Person().hobbies //-> []
- ```
-
-- __type__ {function|String}
:
- Specifies the type of the
- property. The type can be specified as either a function
- that returns the type coerced value or one of the [types](#types-object) names.
-
- ```js
- var Person = DefineMap.extend({
- age: {type: "number"},
- hobbies: {
- type: function(newValue){
- if(typeof newValue === "string") {
- return newValue.split(",")
- } else if( Array.isArray(newValue) ) {
- return newValue;
- }
- }
- }
- });
-
- var me = new Person({age: "33", hobbies: "bball,js"})
- me.age //-> 33
- me.hobbies //-> ["bball","js"]
- ```
-
-- __Type__ {function}
:
- A constructor function that takes
- the value passed to [can.Map::attr attr] as the first argument and called with
- new. For example, if you want whatever
- gets passed to go through `new Array(newValue)` you can do that like:
-
- ```js
- define: {
- items: {
- Type: Array
- }
- }
- ```
-
- If the value passed to [can.Map::attr attr] is already an Array, it will be left as is.
-
-- __set__ {can.Map.prototype.define.set}
:
- A set function that specifies what should happen when an attribute
- is set on a [can.Map]. `set` is called with the result of `type` or `Type`. The following
- defines a `page` setter that updates the map's offset:
-
- ```js
- define: {
- page: {
- set: function(newVal){
- this.attr('offset', (parseInt(newVal) - 1) *
- this.attr('limit'));
- }
- }
- }
- ```
-
-- __get__ {[get](#get-lastsetvalue-)(lastSetValue)}
:
- A function that specifies how the value is retrieved. The get function is
- converted to an [can.compute.async async compute]. It should derive its value from other values
- on the map. The following
- defines a `page` getter that reads from a map's offset and limit:
-
- ```js
- define: {
- page: {
- get: function (newVal) {
- return Math.floor(this.attr('offset') /
- this.attr('limit')) + 1;
- }
- }
- }
- ```
-
- A `get` definition makes the property __computed__ which means it will not be serialized by default.
-
-- __serialize__ {can.Map.prototype.define.serialize|Boolean}
:
- Specifies the behavior of the
- property when [can.Map::serialize serialize] is called.
-
- By default, serialize does not include computed values. Properties with a `get` definition
- are computed and therefore are not added to the result. Non-computed properties values are
- serialized if possible and added to the result.
-
- ```js
- Paginate = can.Map.extend({
- define: {
- pageNum: {
- get: function(){ return this.offset() / 20 }
- }
- }
- });
-
- p = new Paginate({offset: 40});
- p.serialize() //-> {offset: 40}
- ```
-
- If `true` is specified, computed properties will be serialized and added to the result.
-
- ```js
- Paginate = can.Map.extend({
- define: {
- pageNum: {
- get: function(){ return this.offset() / 20 },
- serialize: true
- }
- }
- });
-
- p = new Paginate({offset: 40});
- p.serialize() //-> {offset: 40, pageNum: 2}
- ```
-
- If `false` is specified, non-computed properties will not be added to the result.
-
- ```js
- Paginate = can.Map.extend({
- define: {
- offset: {
- serialize: false
- }
- }
- });
-
- p = new Paginate({offset: 40});
- p.serialize() //-> {}
- ```
-
- If a [can.Map.prototype.define.serialize serialize function] is specified, the result
- of the function is added to the result.
-
- ```js
- Paginate = can.Map.extend({
- define: {
- offset: {
- serialize: function(offset){
- return (offset / 20)+1
- }
- }
- }
- });
-
- p = new Paginate({offset: 40});
- p.serialize() //-> {offset: 3}
- ```
-
-#### types `{Object}`
-
-
-Defines the type, initial value, and get, set, and serialize behavior for an
-observable property. All type converters leave `null` and `undefined` as is except for
-the `"boolean"` type converter.
-
-
-
-##### Object
-
-- __observable__ {function}
:
- The default type behavior. It converts plain Objects to
- [DefineMaps](#new-candefinemapprops) and plain Arrays to [DefineLists](#new-candefinelistitems). Everything else is left as is.
-- __any__ {function}
:
- Leaves the set value as is, performs no type conversion. Aliased as `*`.
-- __string__ {function}
:
- Converts to a string with `""+val`.
-- __date__ {function}
:
- Converts to a JavaScript date using `Date.parse(val)` if a string is given or `new Date(val)` if a number is passed.
-- __number__ {function}
:
- Converts to a number with `+(val)`.
-- __boolean__ {function}
:
- Converts to `false` if `val` is falsey, `"0"`, or `"false"`; otherwise, converts to `true`.
-- __htmlbool__ {function}
:
- Like `boolean`, but converts to `true` if empty string (`""`) is passed.
-- __compute__ {function}
:
- Allows computes to be passed and the property take on the value of the compute.
-- __stringOrObservable__ {function}
:
- Converts plain Objects to [DefineMaps](#new-candefinemapprops), plain Arrays to [DefineLists](#new-candefinelistitems) and everything else to strings. This is useful for routing.
-
-
-## __can-define/map/map__ function
-Create observable objects.
-
-
-### new can.DefineMap([props])
-
-
-Creates a new instance of DefineMap or an extended DefineMap.
-
-```js
-var person = new can.DefineMap({
- first: "Justin",
- last: "Meyer"
-})
-```
-
-
-1. __props__ {Object}
:
- Properties and values to seed the map with.
-
-- __returns__ {[can-define/map/map](#new-candefinemapprops)}
:
- An instance of `can.DefineMap` with the properties from _props_.
-
-
-#### can.DefineMap.extend([name,] [static,] prototype)
-
-
-Extends can.DefineMap, or constructor functions derived from can.DefineMap,
-to create a new constructor function.
-
-```js
-var Person = can.DefineMap.extend(
- "Person",
- {seal: true},
- {
- first: "string",
- last: {type: "string"},
- fullName: {
- get: function(){
- return this.first+" "+this.last;
- }
- },
- age: {value: 0},
- });
-
-var me = new Person({first: "Justin", last: "Meyer"})
-me.fullName //-> "Justin Meyer"
-me.age //-> 0
-```
-
-
-1. __name__ {String}
:
- Provides an optional name for this type that will
- show up nicely in debuggers.
-
-1. __static__ {Object}
:
- Static properties that are set directly on the
- constructor function.
-
-1. __prototype__ {Object\}
:
- A definition of the properties or methods on this type.
-
- If the property definition is a __plain function__, it's considered a method.
-
- ```js
- var Person = DefineMap.extend({
- sayHi: function(){ console.log("hi"); }
- });
-
- var me = new Person();
- me.sayHi();
- ```
-
- If the property definition is a __string__, it's considered a `type` setting to be looked up in [can.define.types](#types-object).
-
- ```js
- var Person = DefineMap.extend({
- age: 'number',
- isCool: 'boolean',
- hobbies: 'observable'
- });
-
- var me = new Person({age: '33', isCool: 'false', hobbies: ['js','bball']});
- me.age //-> 33
- me.isCool //-> false
- me.hobbies instanceof DefineList //-> true
- ```
-
-
- If the property definition is a Constructor function, it's considered a `Type` setting.
-
- ```js
- var Address = DefineMap.extend({
- zip: 'number'
- });
- var Person = DefineMap.extend({
- address: Address
- });
-
- var me = new Person({address: {zip: '60048'}});
- me.address.zip //-> 60048
- ```
-
- If the property is an __object__, it's considered to be a [propDefinition](#propdefinition-object).
-
- ```js
- var Person = DefineMap.extend({
- fullName: {
- get: function() {
- return this.first+" "+this.last;
- },
- set: function(newVal) {
- var parts = newVal.split(" ");
- this.first = parts[0];
- this.last = parts[1];
- }
- },
- // slick way of creating an 'inline' type.
- address: {
- Type: {
- zip: "number"
- }
- }
- });
-
- var me = new Person({fullName: "Rami Myer", address: {zip: '60048'}});
- me.first //-> "Rami"
- me.address.zip //-> 60048
- ```
-
-
-- __returns__ {[can-define/map/map](#new-candefinemapprops)}
:
- A DefineMap constructor function.
-
-#### seal `{Boolean}`
-
-Defines if instances of the map should be [sealed](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal) in development.
-
-
-
-##### Boolean
-If `true`, in development, instances of this object will be [sealed](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal). In [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) errors will be thrown when undefined properties are set. This is the default
-behavior of [extended DefineMaps](#candefinemapextendname-static-prototype):
-
-```js
-"use strict";
-var Person = can.DefineMap.extend({});
-var me = new Person();
-me.age = 33 //-> throws "TypeError: Can't add property age, object is not extensible"
-```
-
-If `false`, the object will not be sealed. This is the default behavior of
-unextended [DefineMaps](#new-candefinemapprops). Use [get](#mapgetpropname) and [set](#mapsetpropname-value) to get and set values:
-
-```js
-var person = new can.DefineMap();
-person.set("first","Justin");
-person.set("last","Meyer");
-
-person.get("first") //-> "Justin"
-person.get("last") //-> "Meyer"
-```
-
-Set `seal` to `false` on objects that have an indeterminate number of properties:
-
-```js
-var Style = can.DefineMap.extend({
- seal: false
-},{
- cssText: {
- get: function(){
- return _.map(this.get(), function(val, prop){
- return prop+": "+val;
- }).join(";")
- }
- }
-});
-var style = new Style();
-style.set("color","green");
-style.set("font","awesome");
-style.cssText //-> "color:green; font: awesome;"
-```
-
-
-#### map.each( callback(item, propName ) )
-
-
-`each` iterates through the Map, calling a function
-for each property value and key.
-
-
-1. __callback__ {function(item, propName)}
:
- the function to call for each property
- The value and key of each property will be passed as the first and second
- arguments, respectively, to the callback. If the callback returns false,
- the loop will stop.
-
-
-- __returns__ {can.Map}
:
- this Map, for chaining
-
-
-#### map.toObject()
-
-
-
-#### map.serialize()
-
-
-
-#### map.get(propName)
-
-
-
-#### map.set(propName, value)
-
-
-
-## __can-define/list/list__ function
-Create observable list.
-
-
-### new can.DefineList([items])
-
-
-
-#### map.item(index, [newVal])
-
-
-
-#### map.items()
-
-
-
-#### list.each( callback(item, index) )
-
-
-`each` iterates through the Map, calling a function
-for each element.
-
-
-1. __callback__ {function(*, Number)}
:
- the function to call for each element
- The value and index of each element will be passed as the first and second
- arguments, respectively, to the callback. If the callback returns false,
- the loop will stop.
-
-
-- __returns__ {can.DefineList}
:
- this DefineList, for chaining
-
-
-#### list.forEach(callback[, thisArg])
-
-
-1. __callback__ {function(element, index, list)}
:
- a function to call with each element of the DefineList
- The three parameters that _callback_ gets passed are _element_, the element at _index_, _index_ the
- current element of the list, and _list_ the DefineList the elements are coming from.
-1. __thisArg__ {Object}
:
- the object to use as `this` inside the callback
-
-
-#### list.splice(index[, howMany[, ...newElements]])
-
-
-1. __index__ {Number}
:
- where to start removing or inserting elements
-
-1. __howMany__ {Number}
:
- the number of elements to remove
- If _howMany_ is not provided, `splice` will remove all elements from `index` to the end of the DefineList.
-
-1. __newElements__ {*}
:
- elements to insert into the DefineList
-
-
-- __returns__ {Array}
:
- the elements removed by `splice`
-
-
-#### list.replace(collection)
-
-
-1. __collection__ {Array|can.DefineList|can.Deferred}
:
- the collection of new elements to use
- If a [can.Deferred] is passed, it must resolve to an `Array` or `can.DefineList`.
- The elements of the list are not actually removed until the Deferred resolves.
-
-
-#### list.push(...elements)
-
-
-`push` adds elements onto the end of a DefineList.
-
-
-1. __elements__ {*}
:
- the elements to add to the DefineList
-
-
-- __returns__ {Number}
:
- the new length of the DefineList
-
-
-#### list.unshift(...elements)
-
-
-`unshift` adds elements onto the beginning of a DefineList.
-
-
-1. __elements__ {*}
:
- the elements to add to the DefineList
-
-
-- __returns__ {Number}
:
- the new length of the DefineList
-
-
-#### list.pop()
-
-
-`pop` removes an element from the end of a DefineList.
-
-
-- __returns__ {*}
:
- the element just popped off the DefineList, or `undefined` if the DefineList was empty
-
-
-#### list.shift()
-
-
-`shift` removes an element from the beginning of a DefineList.
-
-
-- __returns__ {*}
:
- the element just shifted off the DefineList, or `undefined` if the DefineList is empty
-
-
-#### list.indexOf(item)
-
-
-`indexOf` finds the position of a given item in the DefineList.
-
-
-1. __item__ {*}
:
- the item to find
-
-
-- __returns__ {Number}
:
- the position of the item in the DefineList, or -1 if the item is not found.
-
-
-#### list.join(separator)
-
-
-`join` turns a DefineList into a string by inserting _separator_ between the string representations
-of all the elements of the DefineList.
-
-
-1. __separator__ {String}
:
- the string to seperate elements with
-
-
-- __returns__ {String}
:
- the joined string
-
-
-#### list.reverse()
-
-
-`reverse` reverses the elements of the DefineList in place.
-
-
-- __returns__ {can.DefineList}
:
- the DefineList, for chaining
-
-
-#### list.slice([start[, end]])
-
-
-`slice` creates a copy of a portion of the DefineList.
-
+## Documentation
-1. __start__ {Number}
:
- the index to start copying from
+Read the [API docs on CanJS.com](https://canjs.com/doc/can-define.html).
-1. __end__ {Number}
:
- the first index not to include in the copy
- If _end_ is not supplied, `slice` will copy until the end of the list.
+## Changelog
+See the [latest releases on GitHub](https://github.com/canjs/can-define/releases).
-- __returns__ {can.DefineList}
:
- a new `can.DefineList` with the extracted elements
+## Contributing
+The [contribution guide](https://github.com/canjs/can-define/blob/master/CONTRIBUTING.md) has information on getting help, reporting bugs, developing locally, and more.
-#### list.concat(...args)
+## License
+[MIT](https://github.com/canjs/can-define/blob/master/LICENSE.md)
-1. __args__ {Array|can.DefineList|*}
:
- Any number of arrays, Lists, or values to add in
- For each parameter given, if it is an Array or a DefineList, each of its elements will be added to
- the end of the concatenated DefineList. Otherwise, the parameter itself will be added.
diff --git a/document.js b/document.js
deleted file mode 100644
index 8666c5d..0000000
--- a/document.js
+++ /dev/null
@@ -1,18 +0,0 @@
-var bitDocs = require("bit-docs");
-var path = require("path");
-var readmeGenerate = require("bit-docs-generate-readme");
-
-bitDocs(
- path.join(__dirname, "package.json"),
- {
- debug: true,
- readme: {
- apis: "./docs/apis.json"
- },
- generators: [readmeGenerate]
- }).catch(function(e){
-
- setTimeout(function(){
- throw e;
- }, 1);
- });
diff --git a/package.json b/package.json
index 6ab2337..296b46c 100644
--- a/package.json
+++ b/package.json
@@ -50,20 +50,5 @@
"steal-tools": "^1.4.0",
"testee": "^0.7.0",
"bit-docs": "^0.0.7"
- },
- "bit-docs": {
- "dependencies": {
- "bit-docs-glob-finder": "^0.0.5",
- "bit-docs-dev": "^0.0.3",
- "bit-docs-js": "^0.0.4"
- },
- "glob": {
- "pattern": "**/*.{js,md}",
- "ignore": "node_modules/**/*"
- },
- "parent": "can-define",
- "readme": {
- "apis": "./docs/apis.json"
- }
}
-}
+}
\ No newline at end of file