Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

can-route

Package Overview
Dependencies
Maintainers
7
Versions
118
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

can-route - npm Package Compare versions

Comparing version 3.2.4 to 4.0.0-pre.1

src/-url-dispatcher.js

724

can-route.js
/*jshint -W079 */
var canBatch = require('can-event/batch/batch');
var canEvent = require('can-event');
var queues = require("can-queues");
var Observation = require('can-observation');
var compute = require('can-compute');
var SimpleObservable = require("can-simple-observable");
var namespace = require('can-namespace');
var param = require('can-param');
var deparam = require('can-deparam');
var each = require('can-util/js/each/each');
var string = require('can-util/js/string/string');
var isFunction = require('can-util/js/is-function/is-function');
var isEmptyObject = require('can-util/js/is-empty-object/is-empty-object');
var deepAssign = require('can-util/js/deep-assign/deep-assign');
var isWebWorker = require('can-util/js/is-web-worker/is-web-worker');
var isBrowserWindow = require('can-util/js/is-browser-window/is-browser-window');
var makeArray = require('can-util/js/make-array/make-array');
var assign = require("can-util/js/assign/assign");
var types = require('can-types');
var dev = require('can-util/js/dev/dev');
var diff = require('can-util/js/diff/diff');
var diffObject = require('can-util/js/diff-object/diff-object');
var canReflect = require('can-reflect');
var canSymbol = require('can-symbol');
var makeCompute = require("can-simple-observable/make-compute/make-compute");
var SimpleMap = require("can-simple-map");
var registerRoute = require("./src/register");
var urlDispatcher = require("./src/-url-dispatcher");
var urlHelpers = require("./src/url-helpers");
var routeParam = require("./src/param");
var routeDeparam = require("./src/deparam");
var bindingProxy = require("./src/binding-proxy");
var hashchange = require("./src/hashchange");
bindingProxy.bindings.hashchange = hashchange;
bindingProxy.defaultBinding = "hashchange";
// ## route.js

@@ -30,53 +34,14 @@ // `can-route`

// `window.location.hash` with a `Map`._
function canRoute(url, defaults){
registerRoute.register(url, defaults);
return canRoute;
}
//
// Helper methods used for matching routes.
// `RegExp` used to match route variables of the type '{name}'.
// Any word character or a period is matched.
var curliesMatcher = /\{\s*([\w.]+)\s*\}/g;
var colonMatcher = /\:([\w.]+)/g;
// Regular expression for identifying &key=value lists.
var paramsMatcher = /^(?:&[^=]+=[^&]*)+/;
// Converts a JS Object into a list of parameters that can be
// inserted into an html element tag.
var makeProps = function (props) {
var tags = [];
each(props, function (val, name) {
tags.push((name === 'className' ? 'class' : name) + '="' +
(name === "href" ? val : string.esc(val)) + '"');
});
return tags.join(" ");
};
// Checks if a route matches the data provided. If any route variable
// is not present in the data, the route does not match. If all route
// variables are present in the data, the number of matches is returned
// to allow discerning between general and more specific routes.
var matchesData = function (route, data) {
var count = 0,
i = 0,
defaults = {};
// look at default values, if they match ...
for (var name in route.defaults) {
if (route.defaults[name] === data[name]) {
// mark as matched
defaults[name] = 1;
count++;
}
}
for (; i < route.names.length; i++) {
if (!data.hasOwnProperty(route.names[i])) {
return -1;
}
if (!defaults[route.names[i]]) {
count++;
}
}
return count;
};
var location = typeof window !== 'undefined' ? window.location : {};
var wrapQuote = function (str) {
return (str + '')
.replace(/([.?*+\^$\[\]\\(){}|\-])/g, "\\$1");
};
var attrHelper = function (prop, value) {

@@ -123,6 +88,4 @@ if("attr" in this) {

var removeBackslash = function (str) {
return str.replace(/\\/g, "");
};
// A ~~throttled~~ debounced function called multiple times will only fire once the

@@ -140,92 +103,6 @@ // timer runs down. Each call resets the timer.

// A dummy events object used to dispatch url change events on.
var eventsObject = assign({}, canEvent);
var canRoute = function (url, defaults) {
// if route ends with a / and url starts with a /, remove the leading / of the url
var root = canRoute._call("root");
if (root.lastIndexOf("/") === root.length - 1 &&
url.indexOf("/") === 0) {
url = url.substr(1);
}
defaults = defaults || {};
// Extract the variable names and replace with `RegExp` that will match
// an atual URL with values.
var names = [],
res,
test = "",
matcher,
lastIndex,
next,
querySeparator = canRoute._call("querySeparator"),
matchSlashes = canRoute._call("matchSlashes");
// fall back to legacy `:foo` RegExp if necessary
if (colonMatcher.test(url)) {
matcher = colonMatcher;
//!steal-remove-start
dev.warn('update route "' + url + '" to "' + url.replace(colonMatcher, function(name, key) {
return '{' + key + '}';
}) + '"');
//!steal-remove-end
} else {
matcher = curliesMatcher;
}
lastIndex = matcher.lastIndex = 0;
// res will be something like ["{foo}","foo"]
while (res = matcher.exec(url)) {
names.push(res[1]);
test += removeBackslash(url.substring(lastIndex, matcher.lastIndex - res[0].length));
// if matchSlashes is false (the default) don't greedily match any slash in the string, assume its part of the URL
next = "\\" + (removeBackslash(url.substr(matcher.lastIndex, 1)) || querySeparator+(matchSlashes? "": "|/"));
// a name without a default value HAS to have a value
// a name that has a default value can be empty
// The `\\` is for string-escaping giving single `\` for `RegExp` escaping.
test += "([^" + next + "]" + (defaults[res[1]] ? "*" : "+") + ")";
lastIndex = matcher.lastIndex;
}
test += url.substr(lastIndex)
.replace("\\", "");
//!steal-remove-start
// warn if new route uses same map properties as an existing route
each(canRoute.routes, function(r) {
var existingKeys = r.names.concat(Object.keys(r.defaults)).sort();
var keys = names.concat(Object.keys(defaults)).sort();
var sameMapKeys = !diff(existingKeys, keys).length;
var sameDefaultValues = !diffObject(r.defaults, defaults).length;
//the regex removes the trailing slash
var matchingRoutesWithoutTrailingSlash = r.route.replace(/\/$/, "") === url.replace(/\/$/, "");
if (sameMapKeys && sameDefaultValues && !matchingRoutesWithoutTrailingSlash) {
dev.warn('two routes were registered with matching keys:\n' +
'\t(1) route("' + r.route + '", ' + JSON.stringify(r.defaults) + ')\n' +
'\t(2) route("' + url + '", ' + JSON.stringify(defaults) + ')\n' +
'(1) will always be chosen since it was registered first');
}
});
//!steal-remove-end
// Add route in a form that can be easily figured out.
canRoute.routes[url] = {
// A regular expression that will match the route when variable values
// are present; i.e. for (`{page}/{type}`) the `RegExp` is `/([\w\.]*)/([\w\.]*)/` which
// will match for any value of `{page}` and `{type}` (word chars or period).
test: new RegExp("^" + test + "($|" + wrapQuote(querySeparator) + ")"),
// The original URL, same as the index for this entry in routes.
route: url,
// An `array` of all the variable names in this route.
names: names,
// Default values provided for the variables.
defaults: defaults,
// The number of parts in the URL separated by `/`.
length: url.split('/')
.length
};
return canRoute;
};
// If the `route.data` changes, update the hash.

@@ -250,6 +127,15 @@ // Using `.serialize()` retrieves the raw data contained in the `observable`.

var serialized =canRoute.data.serialize(),
path =canRoute.param(serialized, true);
canRoute._call("setURL", path, newProps, old);
route = routeParam.getMatchedRoute(serialized),
path = routeParam.paramFromRoute(route, serialized);
if(route) {
// if we are paraming for setting the hash
// we also want to make sure the route value is updated
// TODO: matched can almost certainly be an observation around the route derived from the serialize data
canRoute.matched(route.route);
}
bindingProxy.call("can.setValue", path, newProps, old);
//canRoute._call("setURL", path, newProps, old);
// trigger a url change so its possible to live-bind on url-based changes
canEvent.dispatch.call(eventsObject,"__url",[path, lastHash]);
urlDispatcher.dispatch("__url",[path, lastHash]);
lastHash = path;

@@ -301,18 +187,4 @@ changedAttrs = [];

// makes sure source has every value in matcher
var matchCheck = function(source, matcher){
/*jshint eqeqeq:false*/
for(var prop in source) {
var s = source[prop],
m = matcher[prop];
if(s && m && typeof s === "object" && typeof matcher === "object") {
return matchCheck(s, m);
}
if(s != m) {
return false;
}
}
return true;
};
var // Deparameterizes the portion of the hash of interest and assign the

@@ -325,3 +197,3 @@ // values to the `route.data` removing existing values no longer in the hash.

setState =canRoute.setState = function () {
var hash =canRoute._call("matchingPartOfURL");
var hash =bindingProxy.call("can.getValue");
var oldParams = curParams;

@@ -334,3 +206,3 @@ curParams =canRoute.deparam(hash);

if (!changingData || hash !== lastHash) {
canRoute.batch.start();
queues.batch.start();
recursiveClean(oldParams, curParams,canRoute.data);

@@ -344,228 +216,17 @@

// trigger a url change so its possible to live-bind on url-based changes
canEvent.dispatch.call(eventsObject,"__url",[hash, lastHash]);
canRoute.batch.stop();
urlDispatcher.dispatch("__url",[hash, lastHash]);
queues.batch.stop();
}
};
var decode = function(str){
try {
return decodeURIComponent(str);
} catch(ex) {
return unescape(str);
}
};
var matchedObservable = new SimpleObservable();
/**
* @static
*/
assign(canRoute, {
Object.defineProperty(canRoute,"routes",{
/**
* @function can-route.param param
* @parent can-route.static
* @description Get a route path from given data.
* @signature `route.param(data)`
* @param {data} object The data to populate the route with.
* @return {String} The route, with the data populated in it.
*
* @body
* Parameterizes the raw JS object representation provided in data.
*
* ```js
* route.param({ type: "video", id: 5 });
* // -> "type=video&id=5"
* ```
*
* If a route matching the provided data is found, that URL is built
* from the data. Any remaining data is added at the end of the
* URL as &amp; separated key/value parameters.
*
* ```js
* route("{type}/{id}");
*
* route.param({ type: "video", id: 5 }) // -> "video/5"
* route.param({ type: "video", id: 5, isNew: false })
* // -> "video/5&isNew=false"
* ```
*/
param: function (data, _setRoute) {
// Check if the provided data keys match the names in any routes;
// Get the one with the most matches.
var route,
// Need to have at least 1 match.
matches = 0,
matchCount,
routeName = data.route,
propCount = 0,
cpy,
res,
after,
matcher;
delete data.route;
each(data, function () {
propCount++;
});
// Otherwise find route.
each(canRoute.routes, function (temp, name) {
// best route is the first with all defaults matching
matchCount = matchesData(temp, data);
if (matchCount > matches) {
route = temp;
matches = matchCount;
}
if (matchCount >= propCount) {
return false;
}
});
// If we have a route name in our `canRoute` data, and it's
// just as good as what currently matches, use that
if (canRoute.routes[routeName] && matchesData(canRoute.routes[routeName], data) === matches) {
route = canRoute.routes[routeName];
}
// If this is match...
if (route) {
cpy = assign({}, data);
// fall back to legacy :foo RegExp if necessary
matcher = colonMatcher.test(route.route) ? colonMatcher : curliesMatcher;
// Create the url by replacing the var names with the provided data.
// If the default value is found an empty string is inserted.
res = route.route.replace(matcher, function (whole, name) {
delete cpy[name];
return data[name] === route.defaults[name] ? "" : encodeURIComponent(data[name]);
})
.replace("\\", "");
// Remove matching default values
each(route.defaults, function (val, name) {
if (cpy[name] === val) {
delete cpy[name];
}
});
// The remaining elements of data are added as
// `&amp;` separated parameters to the url.
after = param(cpy);
// if we are paraming for setting the hash
// we also want to make sure the route value is updated
if (_setRoute) {
canRoute.matched(route.route);
}
return res + (after ? canRoute._call("querySeparator") + after : "");
}
// If no route was found, there is no hash URL, only paramters.
return isEmptyObject(data) ? "" :canRoute._call("querySeparator") + param(data);
},
/**
* @function can-route.deparam deparam
* @parent can-route.static
* @description Extract data from a route path.
* @signature `route.deparam(url)`
*
* Extract data from a url, creating an object representing its values.
*
* ```js
* route("{page}");
*
* var result = route.deparam("page=home");
* console.log(result.page); // -> "home"
* ```
*
* @param {String} url A route fragment to extract data from.
* @return {Object} An object containing the extracted data.
*
* @body
*
* Creates a data object based on the query string passed into it. This is
* useful to create an object based on the `location.hash`.
*
* ```js
* route.deparam("id=5&type=videos");
* // -> { id: 5, type: "videos" }
* ```
*
*
* It's important to make sure the hash or exclamation point is not passed
* to `route.deparam` otherwise it will be included in the first property's
* name.
*
* ```js
* route.data.id = 5 // location.hash -> #!id=5
* route.data.type = "videos"
* // location.hash -> #!id=5&type=videos
* route.deparam(location.hash);
* // -> { #!id: 5, type: "videos" }
* ```
*
* `route.deparam` will try and find a matching route and, if it does,
* will deconstruct the URL and parse out the key/value parameters into the
* data object.
*
* ```js
* route("{type}/{id}");
*
* route.deparam("videos/5");
* // -> { id: 5, route: "{type}/{id}", type: "videos" }
* ```
*/
deparam: function (url) {
// remove the url
var root =canRoute._call("root");
if (root.lastIndexOf("/") === root.length - 1 &&
url.indexOf("/") === 0) {
url = url.substr(1);
}
// See if the url matches any routes by testing it against the `route.test` `RegExp`.
// By comparing the URL length the most specialized route that matches is used.
var route = {
length: -1
},
querySeparator =canRoute._call("querySeparator"),
paramsMatcher =canRoute._call("paramsMatcher");
each(canRoute.routes, function (temp, name) {
if (temp.test.test(url) && temp.length > route.length) {
route = temp;
}
});
// If a route was matched.
if (route.length > -1) {
var // Since `RegExp` backreferences are used in `route.test` (parens)
// the parts will contain the full matched string and each variable (back-referenced) value.
parts = url.match(route.test),
// Start will contain the full matched string; parts contain the variable values.
start = parts.shift(),
// The remainder will be the `&amp;key=value` list at the end of the URL.
remainder = url.substr(start.length - (parts[parts.length - 1] === querySeparator ? 1 : 0)),
// If there is a remainder and it contains a `&amp;key=value` list deparam it.
obj = (remainder && paramsMatcher.test(remainder)) ? deparam(remainder.slice(1)) : {};
// Add the default values for this route.
obj = deepAssign(true, {}, route.defaults, obj);
// Overwrite each of the default values in `obj` with those in
// parts if that part is not empty.
each(parts, function (part, i) {
if (part && part !== querySeparator) {
obj[route.names[i]] = decode(part);
}
});
obj.route = route.route;
return obj;
}
// If no route was matched, it is parsed as a `&amp;key=value` list.
if (url.charAt(0) !== querySeparator) {
url = querySeparator + url;
}
return paramsMatcher.test(url) ? deparam(url.slice(1)) : {};
},
map: function(data){
//!steal-remove-start
dev.warn('Set route.data directly instead of calling route.map');
//!steal-remove-end
canRoute.data = data;
},
/**
* @property {Object} routes

@@ -589,3 +250,36 @@ * @hide

*/
routes: {},
get: function() {
return registerRoute.routes;
},
set: function(newVal) {
return registerRoute.routes = newVal;
}
});
Object.defineProperty(canRoute,"defaultBinding",{
get: function(){
return bindingProxy.defaultBinding;
},
set: function(newVal){
bindingProxy.defaultBinding = newVal;
}
});
Object.defineProperty(canRoute,"currentBinding",{
get: function(){
return bindingProxy.currentBinding;
},
set: function(newVal){
bindingProxy.currentBinding = newVal;
}
});
assign(canRoute, {
param: routeParam,
deparam: routeDeparam,
map: function(data){
//!steal-remove-start
dev.warn('Set route.data directly instead of calling route.map');
//!steal-remove-end
canRoute.data = data;
},
/**

@@ -632,194 +326,7 @@ * @function can-route.ready ready

},
/**
* @function can-route.url url
* @parent can-route.static
* @description Creates a URL fragment based on registered routes given a set of data.
* @signature `route.url(data [, merge])`
*
* Make a URL fragment that when set to window.location.hash will update can-route's properties
* to match those in `data`.
*
* ```js
* route.url({ page: "home" });
* // -> "#!page=home"
* ```
*
* @param {Object} data The data to populate the route with.
* @param {Boolean} [merge] Whether the given options should be merged into
* the current state of the route.
* @return {String} The route URL and query string.
*
* @body
* Similar to [can-route.link], but instead of creating an anchor tag,
* `route.url` creates only the URL based on the route options passed into it.
*
* ```js
* route.url( { type: "videos", id: 5 } );
* // -> "#!type=videos&id=5"
* ```
*
* If a route matching the provided data is found the URL is built from the
* data. Any remaining data is added at the end of the URL as & separated
* key/value parameters.
*
* ```js
* route("{type}/{id}");
*
* route.url( { type: "videos", id: 5 } ) // -> "#!videos/5"
* route.url( { type: "video", id: 5, isNew: false } )
* // -> "#!video/5&isNew=false"
* ```
*/
url: function (options, merge) {
url: urlHelpers.url,
link: urlHelpers.link,
current: urlHelpers.current,
bindings: bindingProxy.bindings,
if (merge) {
Observation.add(eventsObject,"__url");
var baseOptions = canRoute.deparam(canRoute._call("matchingPartOfURL"));
options = assign(assign({}, baseOptions), options);
}
return canRoute._call("root") +canRoute.param(options);
},
/**
* @function can-route.link link
* @parent can-route.static
* @description Creates a string representation of an anchor link using
* data and the registered routes.
* @signature `route.link(innerText, data, props [, merge])`
*
* Make an anchor tag (`<A>`) that when clicked on will update can-route's
* properties to match those in `data`.
*
* @param {Object} innerText The text inside the link.
* @param {Object} data The data to populate the route with.
* @param {Object} props Properties for the anchor other than `href`.
* @param {Boolean} [merge] Whether the given options should be merged into the current state of the route.
* @return {String} A string with an anchor tag that points to the populated route.
*
* @body
* Creates and returns an anchor tag with an href of the route
* attributes passed into it, as well as any properties desired
* for the tag.
*
* ```js
* route.link( "My videos", { type: "videos" }, {}, false )
* // -> <a href="#!type=videos">My videos</a>
* ```
*
* Other attributes besides href can be added to the anchor tag
* by passing in a data object with the attributes desired.
*
* ```js
* route.link( "My videos", { type: "videos" },
* { className: "new" }, false )
* // -> <a href="#!type=videos" class="new">My Videos</a>
* ```
*
* It is possible to utilize the current route options when making anchor
* tags in order to make your code more reusable. If merge is set to true,
* the route options passed into `canRoute.link` will be passed into the
* current ones.
*
* ```js
* location.hash = "#!type=videos"
* route.link( "The zoo", { id: 5 }, true )
* // -> <a href="#!type=videos&id=5">The zoo</true>
*
* location.hash = "#!type=pictures"
* route.link( "The zoo", { id: 5 }, true )
* // -> <a href="#!type=pictures&id=5">The zoo</true>
* ```
*/
link: function (name, options, props, merge) {
return "<a " + makeProps(
assign({
href:canRoute.url(options, merge)
}, props)) + ">" + name + "</a>";
},
/**
* @function can-route.current current
* @parent can-route.static
*
* Check if data represents the current route.
*
* @signature `route.current(data [,subsetMatch] )`
*
* Compares `data` to the current route. Used to verify if an object is
* representative of the current route.
*
* ```
* route.data.set({page: "recipes", id: '5'});
*
* route.current({page: "recipes"}); //-> false
* route.current({page: "recipes"}, true); //-> true
* ```
*
* @param {Object} data Data to check agains the current route.
* @param {Boolean} [subsetMatch] If true, `route.current` will return true
* if every value in `data` matches the current route data, even if
* the route data has additional properties that are not matched. Defaults to `false`
* where every property needs to be present.
* @return {Boolean} Whether the data matches the current URL.
*
* @body
*
* ## Use
*
* Checks the page's current URL to see if the route represents the options
* passed into the function.
*
* Returns true if the options represent the current URL.
*
* ```js
* route.data.id = 5; // location.hash -> "#!id=5"
* route.current({ id: 5 }); // -> true
* route.current({ id: 5, type: 'videos' }); // -> false
*
* route.data.type = 'videos';
* // location.hash -> #!id=5&type=videos
* route.current({ id: 5, type: 'videos' }); // -> true
* ```
*/
current: function (options, subsetMatch) {
// "reads" the url so the url is live-bindable.
Observation.add(eventsObject,"__url");
if(subsetMatch) {
// everything in options shouhld be in baseOptions
var baseOptions = canRoute.deparam(canRoute._call("matchingPartOfURL"));
return matchCheck(options, baseOptions);
} else {
return this._call("matchingPartOfURL") === canRoute.param(options);
}
},
bindings: {
hashchange: {
paramsMatcher: paramsMatcher,
querySeparator: "&",
// don't greedily match slashes in routing rules
matchSlashes: false,
bind: function () {
canEvent.on.call(window, 'hashchange', setState);
},
unbind: function () {
canEvent.on.call(window, 'hashchange', setState);
},
// Gets the part of the url we are determinging the route from.
// For hashbased routing, it's everything after the #, for
// pushState it's configurable
matchingPartOfURL: function () {
var loc =canRoute.location || location;
return loc.href.split(/#!?/)[1] || "";
},
// gets called with the serializedcanRoute data after a route has changed
// returns what the url has been updated to (for matching purposes)
setURL: function (path) {
if(location.hash !== "#" + path) {
location.hash = "!" + path;
}
return path;
},
root: "#!"
}
},
defaultBinding: "hashchange",
currentBinding: null,
// ready calls setup

@@ -838,4 +345,4 @@ // setup binds and listens to data changes

if (!canRoute.currentBinding) {
canRoute._call("bind");
canRoute.serializedCompute.addEventListener("change", onRouteDataChange);
bindingProxy.call("can.onValue", setState);
canReflect.onValue( canRoute.serializedObservation, onRouteDataChange, "notify");
canRoute.currentBinding =canRoute.defaultBinding;

@@ -846,4 +353,4 @@ }

if (canRoute.currentBinding) {
canRoute._call("unbind");
canRoute.serializedCompute.removeEventListener("change", onRouteDataChange);
bindingProxy.call("can.offValue", setState);
canReflect.offValue( canRoute.serializedObservation, onRouteDataChange, "notify");
canRoute.currentBinding = null;

@@ -854,14 +361,2 @@ }

},
// a helper to get stuff from the current or default bindings
_call: function () {
var args = makeArray(arguments),
prop = args.shift(),
binding =canRoute.bindings[canRoute.currentBinding ||canRoute.defaultBinding],
method = binding[prop];
if (method.apply) {
return method.apply(binding, args);
} else {
return method;
}
},
/**

@@ -888,3 +383,3 @@ * @function can-route.matched matched

*/
matched: compute()
matched: makeCompute( matchedObservable )
});

@@ -897,3 +392,3 @@

if (!canRoute.data[name]) {
return;
return canRoute.data.addEventListener.apply(canRoute.data, args);
}

@@ -904,6 +399,6 @@ return canRoute.data[name].apply(canRoute.data, args);

each(['addEventListener','removeEventListener','bind', 'unbind', 'on', 'off'], function(name) {
// exposing all internal canEvent evt's to canRoute
// exposing all internal eventQueue evt's to canRoute
canRoute[name] = function(eventName) {
if (eventName === '__url') {
return canEvent[name].apply(eventsObject, arguments);
return urlDispatcher[name].apply(urlDispatcher, arguments);
}

@@ -928,9 +423,19 @@ return bindToCanRouteData(name, arguments);

};
var serializedObservation;
var serializedCompute;
Object.defineProperty(canRoute,"serializedObservation", {
get: function(){
if(!serializedObservation) {
serializedObservation = new Observation(function canRouteSerialized(){
return canReflect.serialize( canRoute.data );
});
}
return serializedObservation;
}
});
Object.defineProperty(canRoute,"serializedCompute", {
get: function(){
if(!serializedCompute) {
serializedCompute = compute(function(){
return canRoute.data.serialize();
});
serializedCompute = makeCompute(canRoute.serializedObservation);
}

@@ -944,17 +449,4 @@ return serializedCompute;

return routeData;
} else if( types.DefaultMap ) {
if( types.DefaultMap.prototype.toObject ) {
var DefaultRouteMap = types.DefaultMap.extend({
seal: false
},{
"*": "stringOrObservable"
});
return setRouteData(new DefaultRouteMap());
} else {
return setRouteData( stringCoercingMapDecorator( new types.DefaultMap() ) );
}
} else {
throw new Error("can.route.data accessed without being set");
return setRouteData( stringCoercingMapDecorator( new SimpleMap() ) );
}

@@ -975,4 +467,2 @@ },

canRoute.attr = function(){

@@ -982,4 +472,2 @@ return attrHelper.apply(canRoute.data,arguments);

//Allow for overriding of route batching by can.transaction
canRoute.batch = canBatch;

@@ -986,0 +474,0 @@ canReflect.setKeyValue(canRoute, canSymbol.for("can.isFunctionLike"), false);

@@ -5,4 +5,3 @@ @function can-route can-route

@test can-route/test.html
@parent can-routing
@collection can-core
@parent can-core
@link ../docco/route/route.html docco

@@ -9,0 +8,0 @@ @package ./package.json

{
"name": "can-route",
"version": "3.2.4",
"version": "4.0.0-pre.1",
"description": "",

@@ -17,5 +17,4 @@ "homepage": "",

"scripts": {
"preversion": "npm test && npm run build",
"version": "git commit -am \"Update dist for release\" && git checkout -b release && git add -f dist/",
"postversion": "git push --tags && git checkout master && git branch -D release && git push",
"preversion": "npm test",
"postpublish": "git push --tags && git push",
"testee": "testee test/test.html --browsers firefox",

@@ -28,3 +27,2 @@ "test": "npm run detect-cycle && npm run jshint && npm run testee",

"release:major": "npm version major && npm publish",
"build": "node build.js",
"develop": "done-serve --static --develop --port 8080",

@@ -45,19 +43,18 @@ "detect-cycle": "detect-cyclic-packages --ignore done-serve"

"dependencies": {
"can-compute": "^3.3.1",
"can-deparam": "^1.0.1",
"can-event": "^3.6.0",
"can-event-queue": "<2.0.0",
"can-namespace": "1.0.0",
"can-observation": "^3.3.1",
"can-observation": "^4.0.0-pre.19",
"can-observation-recorder": "<2.0.0",
"can-param": "^1.0.1",
"can-reflect": "^1.2.1",
"can-simple-map": "^3.3.0",
"can-queues": "<2.0.0",
"can-reflect": "^1.6.0",
"can-simple-map": "^4.0.0-pre.9",
"can-simple-observable": "^2.0.0-pre.21",
"can-symbol": "^1.0.0",
"can-types": "^1.1.0",
"can-util": "^3.9.0"
},
"devDependencies": {
"can-define": "^1.3.3",
"can-list": "^3.2.0",
"can-map": "^3.3.1",
"can-stache-key": "^0.1.0",
"can-define": "^2.0.0-pre.0",
"can-stache-key": "^1.0.0-pre.0",
"detect-cyclic-packages": "^1.1.0",

@@ -64,0 +61,0 @@ "done-serve": "^0.2.0",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc