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

can-route

Package Overview
Dependencies
Maintainers
12
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 4.1.2 to 4.2.0-pre.1

doc/urlData.md

94

can-route.js
/*jshint -W079 */
var Bind = require("can-bind");
var queues = require("can-queues");

@@ -17,3 +18,3 @@ var Observation = require('can-observation');

var bindingProxy = require("./src/binding-proxy");
var hashchange = require("./src/hashchange");
var Hashchange = require("can-route-hash");

@@ -23,7 +24,8 @@ var isWebWorker = require('can-globals/is-web-worker/is-web-worker');

var hashchangeObservable = new Hashchange();
bindingProxy.bindings.hashchange = hashchangeObservable;
bindingProxy.defaultBinding = "hashchange";
bindingProxy.urlDataObservable.value = hashchangeObservable;
bindingProxy.bindings.hashchange = hashchange;
bindingProxy.defaultBinding = "hashchange";
// ## route.js

@@ -36,3 +38,5 @@ // `can-route`

//!steal-remove-start
devLog.warn('Call route.register(url,defaults) instead of calling route(url, defaults)');
if(process.env.NODE_ENV !== 'production') {
devLog.warn('Call route.register(url,defaults) instead of calling route(url, defaults)');
}
//!steal-remove-end

@@ -75,9 +79,2 @@ registerRoute.register(url, defaults);

//!steal-remove-start
Object.defineProperty(updateUrl, "name", {
value: "can-route.updateUrl"
});
//!steal-remove-end
// Deparameterizes the portion of the hash of interest and assign the

@@ -102,7 +99,2 @@ // values to the `route.data` removing existing values no longer in the hash.

}
//!steal-remove-start
Object.defineProperty(updateRouteData, "name", {
value: "can-route.updateRouteData"
});
//!steal-remove-end

@@ -146,10 +138,15 @@

bindingProxy.defaultBinding = newVal;
var observable = bindingProxy.bindings[bindingProxy.defaultBinding];
if(observable) {
bindingProxy.urlDataObservable.value = observable;
}
}
});
Object.defineProperty(canRoute,"currentBinding",{
Object.defineProperty(canRoute,"urlData",{
get: function(){
return bindingProxy.currentBinding;
return bindingProxy.urlDataObservable.value;
},
set: function(newVal){
bindingProxy.currentBinding = newVal;
canRoute._teardown();
bindingProxy.urlDataObservable.value = newVal;
}

@@ -163,3 +160,5 @@ });

//!steal-remove-start
devLog.warn('Set route.data directly instead of calling route.map');
if(process.env.NODE_ENV !== 'production') {
devLog.warn('Set route.data directly instead of calling route.map');
}
//!steal-remove-end

@@ -206,13 +205,50 @@ canRoute.data = data;

_setup: function () {
if (!canRoute.currentBinding) {
bindingProxy.call("can.onValue", updateRouteData);
canReflect.onValue( canRoute.serializedObservation, updateUrl, "notify");
canRoute.currentBinding =canRoute.defaultBinding;
if (!canRoute._canBinding) {
var bindingOptions = {
// The parent is the hashchange observable
parent: bindingProxy.urlDataObservable.value,
setParent: updateUrl,
// The child is route.data
child: canRoute.serializedObservation,
setChild: updateRouteData,
// On init, we do not want the child set to the parent’s value; this is
// handled by start() for reasons mentioned there.
onInitDoNotUpdateChild: true,
// Cycles are allowed because updateUrl is async; if another change
// happens during its setTimeout, then without cycles the change would
// be ignored :( TODO: Can this be removed if updateUrl stops using
// setTimeout in a major version?
cycles: 1,
// Listen for changes in the notify queue
queue: "notify"
};
// For debugging: the names that will be assigned to the updateChild and
// updateParent functions within can-bind
//!steal-remove-start
if (process.env.NODE_ENV !== 'production') {
bindingOptions.updateChildName = "can-route.updateRouteData";
bindingOptions.updateParentName = "can-route.updateUrl";
}
//!steal-remove-end
// Create a new binding with can-bind
canRoute._canBinding = new Bind(bindingOptions);
// …and turn it on!
canRoute._canBinding.start();
}
},
_teardown: function () {
if (canRoute.currentBinding) {
bindingProxy.call("can.offValue", updateRouteData);
canReflect.offValue( canRoute.serializedObservation, updateUrl, "notify");
canRoute.currentBinding = null;
if (canRoute._canBinding) {
canRoute._canBinding.stop();
canRoute._canBinding = null;
}

@@ -219,0 +255,0 @@ clearTimeout(timer);

@@ -20,7 +20,9 @@ @module {Object} can-route can-route

{
data, // The bound observable.
data, // The bound key-value observable.
urlData, // The observable that represents the
// hash. Defaults to RouteHash.
register, // Register routes that translate between
// the url and the bound observable.
// the url and the bound observable.
start, // Begin updating the bound observable with
// url data and vice versa.
// url data and vice versa.
deparam, // Given url fragment, return the data for it.

@@ -32,3 +34,3 @@ rule, // Given url fragment, return the routing rule

isCurrent, // Given data, return true if the current url matches
// the data.
// the data.
currentRule // Return the matched rule name.

@@ -35,0 +37,0 @@ }

@@ -15,4 +15,4 @@ @function can-route.currentRule currentRule

```js
route( "{type}", { type: "foo" } );
route( "{type}/{subtype}" );
route.register( "{type}", { type: "foo" } );
route.register( "{type}/{subtype}" );
route.currentRule(); // "{type}"

@@ -19,0 +19,0 @@ route.data.subtype = "foo";

@property {Object|HTMLElement} can-route.data data
@parent can-route.static
This is the internal observable object underlying [can-route]. It can be set in order to cross-bind a top level state object (Application ViewModel) to can-route.
An observable key-value object used to cross bind to the url observable [can-route.urlData]. Set it to cross-bind a top level state object (Application ViewModel) to [can-route].

@@ -6,0 +6,0 @@ @type {Object} If `route.data` is set to a [can-reflect]ed observable object of

{
"name": "can-route",
"version": "4.1.2",
"version": "4.2.0-pre.1",
"description": "Observable front-end application routing for CanJS.",

@@ -36,2 +36,3 @@ "homepage": "https://canjs.com/doc/can-route.html",

"dependencies": {
"can-bind": "<2.0.0",
"can-deparam": "^1.0.1",

@@ -52,3 +53,4 @@ "can-dom-events": "^1.1.0",

"can-symbol": "^1.0.0",
"can-util": "^3.9.0"
"can-util": "^3.9.0",
"can-route-hash": "<2.0.0"
},

@@ -59,2 +61,3 @@ "devDependencies": {

"can-observe": "^2.0.0",
"can-route-mock": "<2.0.0",
"can-stache-key": "^1.0.0",

@@ -67,4 +70,4 @@ "detect-cyclic-packages": "^1.1.0",

"steal-tools": "^1.1.2",
"testee": "^0.7.0"
"testee": "^0.8.0"
}
}

@@ -5,12 +5,7 @@ var canReflect = require('can-reflect');

var defaultBinding = new SimpleObservable("hashchange");
var urlDataObservable = new SimpleObservable(null);
var bindingProxy = {
get defaultBinding(){
return defaultBinding.get();
},
set defaultBinding(newVal){
defaultBinding.set(newVal);
},
currentBinding: null,
defaultBinding: null,
urlDataObservable: urlDataObservable,
bindings: {},

@@ -20,4 +15,7 @@ call: function(){

prop = args.shift(),
binding = bindingProxy.bindings[bindingProxy.currentBinding ||bindingProxy.defaultBinding],
method = binding[prop.indexOf("can.") === 0 ? canSymbol.for(prop) : prop];
binding = urlDataObservable.value;
if(binding === null) {
throw new Error("there is no current binding!!!");
}
var method = binding[prop.indexOf("can.") === 0 ? canSymbol.for(prop) : prop];
if (method.apply) {

@@ -24,0 +22,0 @@ return method.apply(binding, args);

@@ -54,3 +54,3 @@ var deparam = require('can-deparam');

* ```js
* route("{page}");
* route.register("{page}");
*

@@ -92,3 +92,3 @@ * var result = route.deparam("page=home");

* ```js
* route("{type}/{id}");
* route.register("{type}/{id}");
*

@@ -95,0 +95,0 @@ * route.deparam("videos/5");

@@ -135,3 +135,3 @@ var canReflect = require("can-reflect");

* ```js
* route("{type}/{id}");
* route.register("{type}/{id}");
*

@@ -138,0 +138,0 @@ * route.param({ type: "video", id: 5 }) // -> "video/5"

@@ -52,5 +52,7 @@ // This file contains the function that allows the registration of routes

//!steal-remove-start
dev.warn('update route "' + url + '" to "' + url.replace(regexps.colon, function(name, key) {
return '{' + key + '}';
}) + '"');
if(process.env.NODE_ENV !== 'production') {
dev.warn('update route "' + url + '" to "' + url.replace(regexps.colon, function(name, key) {
return '{' + key + '}';
}) + '"');
}
//!steal-remove-end

@@ -78,18 +80,20 @@ } else {

//!steal-remove-start
// warn if new route uses same map properties as an existing route
canReflect.eachKey(RouteRegistry.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(process.env.NODE_ENV !== 'production') {
// warn if new route uses same map properties as an existing route
canReflect.eachKey(RouteRegistry.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');
}
});
if (sameMapKeys && sameDefaultValues && !matchingRoutesWithoutTrailingSlash) {
dev.warn('two routes were registered with matching keys:\n' +
'\t(1) route.register("' + r.route + '", ' + JSON.stringify(r.defaults) + ')\n' +
'\t(2) route.register("' + url + '", ' + JSON.stringify(defaults) + ')\n' +
'(1) will always be chosen since it was registered first');
}
});
}
//!steal-remove-end

@@ -96,0 +100,0 @@ // Add route in a form that can be easily figured out.

@@ -73,3 +73,3 @@ var bindingProxy = require("./binding-proxy");

* ```js
* route("{type}/{id}");
* route.register("{type}/{id}");
*

@@ -76,0 +76,0 @@ * route.url( { type: "videos", id: 5 } ) // -> "#!videos/5"

@@ -13,3 +13,3 @@ var canRoute = require('can-route');

canRoute.routes = {};
canRoute("{foo}");
canRoute.register("{foo}");
var res = canRoute.link("Hello", {

@@ -16,0 +16,0 @@ foo: "bar",

var canRoute = require("can-route");
var SimpleObservable = require("can-simple-observable");
var SimpleMap = require("can-simple-map");
var canReflect = require("can-reflect");
var routeValue;
canRoute.bindings.mock = canReflect.assignSymbols({
paramsMatcher: /^(?:&[^=]+=[^&]*)+/,
querySeparator: "&",
// don't greedily match slashes in routing rules
matchSlashes: false,
root: "#!"
},{
"can.onValue": function(handler){
routeValue.on(handler);
},
"can.offValue": function(handler) {
routeValue.off(handler);
},
// 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
"can.getValue": function() {
return routeValue.get().split(/#!?/)[1] || "";
},
// gets called with the serializedcanRoute data after a route has changed
// returns what the url has been updated to (for matching purposes)
"can.setValue": function(path){
if(path[0] !== "#") {
routeValue.set("#"+(path || ""));
} else {
routeValue.set(path || "");
}
return path;
}
});
var RouteMock = require("can-route-mock");

@@ -43,8 +12,7 @@ var oldDefault;

// discard old hash
this.hash = routeValue = new SimpleObservable("");
oldDefault = canRoute.defaultBinding;
canRoute._teardown();
canRoute.currentBinding = null;
canRoute.defaultBinding = "mock";
routeValue.set("");
this.hash = new RouteMock();
oldDefault = canRoute.urlData;
canRoute.urlData = this.hash;
this.hash.value = "";
canRoute.data = new SimpleMap();

@@ -55,9 +23,9 @@ //canRoute._setup();

canRoute._teardown();
canRoute.defaultBinding = oldDefault;
this.hash = routeValue = new SimpleObservable("");
canRoute.urlData = oldDefault;
this.hash = new RouteMock();
canRoute.data = new SimpleMap();
//canRoute.bindings.mock.unbind();
//canRoute._setup();
},
hash: routeValue
}
};

@@ -521,4 +521,4 @@ var canRoute = require('can-route');

var expectedWarningText = 'two routes were registered with matching keys:\n' +
'\t(1) route("login", {"page":"auth"})\n' +
'\t(2) route("signup", {"page":"auth"})\n' +
'\t(1) route.register("login", {"page":"auth"})\n' +
'\t(2) route.register("signup", {"page":"auth"})\n' +
'(1) will always be chosen since it was registered first';

@@ -525,0 +525,0 @@

@@ -15,3 +15,4 @@ /* jshint asi:true */

canRoute._teardown();
canRoute.defaultBinding = "hashchange";
canRoute.urlData = canRoute.bindings.hashchange
//canRoute.defaultBinding = "hashchange";
this.fixture = document.getElementById("qunit-fixture");

@@ -69,19 +70,2 @@ }

});
//require("can-queues").log("flush");
/*test("initial route fires twice", function () {
stop();
expect(1);
window.routeTestReady = function (iCanRoute, loc) {
iCanRoute("", {});
debugger;
iCanRoute.matched.bind('change', function(){
ok(true, 'change triggered once')
start();
});
iCanRoute.start();
}
var iframe = document.createElement('iframe');
iframe.src = __dirname+"/define-testing.html?5";
this.fixture.appendChild(iframe);
});*/

@@ -119,7 +103,7 @@ test("removing things from the hash", function () {

iCanRoute("{type}/{id}");
iCanRoute.register("{type}/{id}");
var AppState = DefineMap.extend({seal: false},{});
var appState = new AppState({type: "dog", id: '4'});
iCanRoute.map(appState);
iCanRoute.data = appState;

@@ -147,3 +131,3 @@ loc.hash = "#!cat/5";

canRoute("{type}/{id}");
canRoute.register("{type}/{id}");
var AppState = DefineMap.extend({seal: false},{});

@@ -153,3 +137,3 @@ var appState = new AppState({section: 'home'});

canRoute.data = appState;
mockRoute.hash.set("#!cat/5"); // type and id get added ... this will call update url to add everything
mockRoute.hash.value = "#!cat/5"; // type and id get added ... this will call update url to add everything
canRoute.start();

@@ -159,3 +143,3 @@

equal(mockRoute.hash.get(), "#cat/5&section=home", "same URL");
equal(mockRoute.hash.value, "cat/5&section=home", "same URL");
equal(appState.get("type"), "cat", "hash populates the appState");

@@ -178,3 +162,3 @@ equal(appState.get("id"), "5", "hash populates the appState");

iCanRoute.start();
iCanRoute("{type}/{id}");
iCanRoute.register("{type}/{id}");
iCanRoute.attr({

@@ -201,4 +185,4 @@ type: "bar",

mockRoute.start();
canRoute("active");
canRoute("");
canRoute.register("active");
canRoute.register("");

@@ -211,3 +195,3 @@ mockRoute.hash.set("#active");

var after = mockRoute.hash.get();
equal(after, "#active");
equal(after, "active");
mockRoute.stop();

@@ -222,4 +206,4 @@ QUnit.start();

iCanRoute.start();
iCanRoute("{type}");
iCanRoute("{type}/{id}");
iCanRoute.register("{type}");
iCanRoute.register("{type}/{id}");
iCanRoute.attr({

@@ -238,3 +222,3 @@ type: "bar"

// check for 1 second
var time = new Date()
var time = new Date();
setTimeout(function innerTimer() {

@@ -245,3 +229,3 @@ var after = loc.href.substr(loc.href.indexOf("#"));

if (isMatch || isWaitingTooLong) {
equal(after, "#!bar/" + encodeURIComponent("\/"), "should go to type/id");
equal(after, "#!bar/" + encodeURIComponent("\/"), "should go to type/id "+ (new Date() - time));
teardownRouteTest();

@@ -330,3 +314,3 @@ } else {

route.map(appVM);
route.data = appVM;
route.start();

@@ -355,3 +339,3 @@

route.map(appVM);
route.data = appVM;
route.start();

@@ -377,3 +361,3 @@

iCanRoute.start();
iCanRoute("{path}");
iCanRoute.register("{path}");

@@ -416,3 +400,3 @@ iCanRoute.attr('path', 'foo');

canRoute.routes = {};
canRoute("{page}\\.html", {
canRoute.register("{page}\\.html", {
page: "index"

@@ -488,3 +472,3 @@ });

route.routes = {};
route("{type}/{id}");
route.register("{type}/{id}");

@@ -534,3 +518,3 @@ route.attr({

canRoute.map(appState);
canRoute.data = appState;
canRoute.start();

@@ -545,3 +529,3 @@

setTimeout(function(){
equal( mockRoute.hash.get(), "#");
equal( mockRoute.hash.get(), "");
mockRoute.stop();

@@ -562,3 +546,3 @@ start();

canRoute.map(appState);
canRoute.data = appState;
canRoute.start();

@@ -589,3 +573,3 @@

canRoute.routes = {};
canRoute("{ page }", {
canRoute.register("{ page }", {
page: "index"

@@ -599,3 +583,3 @@ })

canRoute("pages/{ p1 }/{ p2 }/{ p3 }", {
canRoute.register("pages/{ p1 }/{ p2 }/{ p3 }", {
p1: "index",

@@ -629,4 +613,4 @@ p2: "foo",

canRoute.data = appState;
canRoute('{page}');
canRoute('{page}/{section}');
canRoute.register('{page}');
canRoute.register('{page}/{section}');

@@ -633,0 +617,0 @@ QUnit.stop();

@@ -99,7 +99,7 @@ /* jshint asi:true */

iCanRoute("{type}/{id}");
iCanRoute.register("{type}/{id}");
var AppState = win.CanMap.extend();
var appState = new AppState({type: "dog", id: '4'});
iCanRoute.map(appState);
iCanRoute.data = appState;

@@ -125,7 +125,7 @@ loc.hash = "#!cat/5";

iCanRoute("{type}/{id}");
iCanRoute.register("{type}/{id}");
var AppState = win.CanMap.extend();
var appState = new AppState({section: 'home'});
iCanRoute.map(appState);
iCanRoute.data = appState;
loc.hash = "#!cat/5";

@@ -155,3 +155,3 @@ iCanRoute.start();

iCanRoute.start();
iCanRoute("{type}/{id}");
iCanRoute.register("{type}/{id}");
iCanRoute.attr({

@@ -178,4 +178,4 @@ type: "bar",

iCanRoute.start()
iCanRoute("active");
iCanRoute("");
iCanRoute.register("active");
iCanRoute.register("");

@@ -198,4 +198,4 @@ loc.hash = "#!active";

iCanRoute.start();
iCanRoute("{type}");
iCanRoute("{type}/{id}");
iCanRoute.register("{type}");
iCanRoute.register("{type}/{id}");
iCanRoute.attr({

@@ -276,3 +276,3 @@ type: "bar"

route.map(appVM);
route.data = appVM;
route.start();

@@ -293,26 +293,2 @@

/*test("updating unserialized prop on bound can.Map causes single update without a coerced string value", function() {
expect(1);
setupRouteTest(function (iframe, route) {
var appVM = new (Map.extend({define: {
action: {serialize: false}
}}))();
route.map(appVM);
route.start();
appVM.bind('action', function(ev, newVal) {
equal(typeof newVal, 'function');
});
appVM.attr('action', function() {});
// check after 30ms to see that we only have a single call
setTimeout(function() {
teardownRouteTest();
}, 5);
});
});*/
test("hash doesn't update to itself with a !", function() {

@@ -323,3 +299,3 @@ stop();

iCanRoute.start();
iCanRoute("{path}");
iCanRoute.register("{path}");

@@ -362,3 +338,3 @@ iCanRoute.attr('path', 'foo');

canRoute.routes = {};
canRoute("{page}\\.html", {
canRoute.register("{page}\\.html", {
page: "index"

@@ -434,3 +410,3 @@ });

route.routes = {};
route("{type}/{id}");
route.register("{type}/{id}");

@@ -437,0 +413,0 @@ route.attr({

@@ -6,2 +6,5 @@ var canRoute = require('can-route');

var queues = require("can-queues");
var canReflect = require("can-reflect");
QUnit.module("can-route observe",{

@@ -25,8 +28,8 @@ setup: function(){

mockRoute.hash.on(function handler1(newVal){
canReflect.onValue( mockRoute.hash, function handler1(newVal){
QUnit.equal(newVal, "#&name=Brian", "updated hash");
mockRoute.hash.off(handler1);
canReflect.offValue( mockRoute.hash, handler1);
QUnit.equal(canRoute.data.name, 'Brian', 'appState is bound to canRoute');
mockRoute.hash.on(function handler2(newVal){
canReflect.onValue( mockRoute.hash, function handler2(newVal){
equal( newVal, "#");

@@ -33,0 +36,0 @@ mockRoute.stop();

@@ -28,3 +28,3 @@ var canRoute = require('can-route');

setTimeout(function(){
QUnit.equal(hash.get(), "#home", "set to home");
QUnit.equal(hash.get(), "home", "set to home");

@@ -38,3 +38,3 @@ canRoute.stop();

setTimeout(function(){
QUnit.equal(hash.get(), "#cart", "now it is the cart");
QUnit.equal(hash.get(), "cart", "now it is the cart");
QUnit.start();

@@ -41,0 +41,0 @@ }, 30);

@@ -6,2 +6,4 @@ var canRoute = require('can-route');

var mockRoute = require("./mock-route-binding");
var RouteMock = require("can-route-mock");
var canReflect = require("can-reflect");

@@ -16,4 +18,4 @@ QUnit.module("can-route .url",{

QUnit.stop();
mockRoute.start();
var oldUsing = canRoute.urlData;
var mock = canRoute.urlData = new RouteMock();
var AppState = DefineMap.extend({seal: false},{"*": "stringOrObservable"});

@@ -23,10 +25,8 @@ var appState = new AppState({});

canRoute.map(appState);
canRoute.data = appState;
canRoute.start();
appState.update({'foo': 'bar',page: "recipe", id: 5});
appState.set({'foo': 'bar',page: "recipe", id: 5});
mockRoute.hash.on(function(){
canReflect.onValue(mock,function(){
QUnit.equal(canRoute.url({}, true), "#!&foo=bar&page=recipe&id=5", "empty");

@@ -39,3 +39,3 @@ QUnit.ok(canRoute.url({page: "recipe"}, true), "page:recipe is true");

setTimeout(function(){
mockRoute.stop();
canRoute.urlData = oldUsing;
QUnit.start();

@@ -42,0 +42,0 @@ },20);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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