Skip to content
This repository has been archived by the owner on Sep 20, 2020. It is now read-only.

Commit

Permalink
release 0.0.12
Browse files Browse the repository at this point in the history
  • Loading branch information
christopherthielen committed Feb 1, 2015
1 parent 4dedab2 commit b6db4cf
Show file tree
Hide file tree
Showing 20 changed files with 3,304 additions and 610 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ui-router-extras",
"version": "0.0.12-pre1",
"version": "0.0.12",
"authors": [
"Chris Thielen <ui-router-extras@sandgnat.com>"
],
Expand Down
2 changes: 1 addition & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ gulp.task('karma:modules', ['scripts'], function() {
gulp.task('karma:versions', ['scripts'], function() {
var karma = require('karma').server;
var Q = require('q');
var versions = [ '0.2.8', '0.2.10', '0.2.11', '0.2.13' ];
var versions = [ '0.2.8', '0.2.10', '0.2.12', '0.2.13' ];
var dynamicconf = require("./test/conf/karma.dynamic.conf");

var promise = Q(true);
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"author": "Christopher Thielen",
"name": "ui-router-extras",
"version": "0.0.12-pre1",
"version": "0.0.12",
"description": "UI-Router Extras: Sticky states, Future States, Deep State Redirect, Transition promise",
"homepage": "http://christopherthielen.github.io/ui-router-extras/",
"dependencies": {},
Expand All @@ -18,9 +18,9 @@
"gulp-uglify": "^1.1.0",
"gulp-jshint": "^1.9.0",
"gulp-notify": "^2.1.0",
"del": "^1.1.1",
"gulp-wrap": "^0.10.1",
"gulp-karma": "0.0.4",
"del": "^1.1.1",
"q": "^1.1.2",
"run-sequence": "^1.0.2"
},
Expand Down
1,004 changes: 677 additions & 327 deletions release/ct-ui-router-extras.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion release/ct-ui-router-extras.min.js

Large diffs are not rendered by default.

174 changes: 174 additions & 0 deletions release/modular/ct-ui-router-extras.core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
(function(angular, undefined){
"use strict";
var mod_core = angular.module("ct.ui.router.extras.core", [ "ui.router" ]);

var internalStates = {}, stateRegisteredCallbacks = [];
mod_core.config([ '$stateProvider', '$injector', function ($stateProvider, $injector) {
// Decorate any state attribute in order to get access to the internal state representation.
$stateProvider.decorator('parent', function (state, parentFn) {
// Capture each internal UI-Router state representations as opposed to the user-defined state object.
// The internal state is, e.g., the state returned by $state.$current as opposed to $state.current
internalStates[state.self.name] = state;
// Add an accessor for the internal state from the user defined state
state.self.$$state = function () {
return internalStates[state.self.name];
};

angular.forEach(stateRegisteredCallbacks, function(callback) { callback(state); });
return parentFn(state);
});
}]);

var DEBUG = false;

var forEach = angular.forEach;
var extend = angular.extend;
var isArray = angular.isArray;

var map = function (collection, callback) {
"use strict";
var result = [];
forEach(collection, function (item, index) {
result.push(callback(item, index));
});
return result;
};

var keys = function (collection) {
"use strict";
return map(collection, function (collection, key) {
return key;
});
};

var filter = function (collection, callback) {
"use strict";
var result = [];
forEach(collection, function (item, index) {
if (callback(item, index)) {
result.push(item);
}
});
return result;
};

var filterObj = function (collection, callback) {
"use strict";
var result = {};
forEach(collection, function (item, index) {
if (callback(item, index)) {
result[index] = item;
}
});
return result;
};

// Duplicates code in UI-Router common.js
function ancestors(first, second) {
var path = [];

for (var n in first.path) {
if (first.path[n] !== second.path[n]) break;
path.push(first.path[n]);
}
return path;
}

// Duplicates code in UI-Router common.js
function objectKeys(object) {
if (Object.keys) {
return Object.keys(object);
}
var result = [];

angular.forEach(object, function (val, key) {
result.push(key);
});
return result;
}

/**
* like objectKeys, but includes keys from prototype chain.
* @param object the object whose prototypal keys will be returned
* @param ignoreKeys an array of keys to ignore
*/
// Duplicates code in UI-Router common.js
function protoKeys(object, ignoreKeys) {
var result = [];
for (var key in object) {
if (!ignoreKeys || ignoreKeys.indexOf(key) === -1)
result.push(key);
}
return result;
}

// Duplicates code in UI-Router common.js
function arraySearch(array, value) {
if (Array.prototype.indexOf) {
return array.indexOf(value, Number(arguments[2]) || 0);
}
var len = array.length >>> 0, from = Number(arguments[2]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);

if (from < 0) from += len;

for (; from < len; from++) {
if (from in array && array[from] === value) return from;
}
return -1;
}

// Duplicates code in UI-Router common.js
// Added compatibility code (isArray check) to support both 0.2.x and 0.3.x series of UI-Router.
function inheritParams(currentParams, newParams, $current, $to) {
var parents = ancestors($current, $to), parentParams, inherited = {}, inheritList = [];

for (var i in parents) {
if (!parents[i].params) continue;
// This test allows compatibility with 0.2.x and 0.3.x (optional and object params)
parentParams = isArray(parents[i].params) ? parents[i].params : objectKeys(parents[i].params);
if (!parentParams.length) continue;

for (var j in parentParams) {
if (arraySearch(inheritList, parentParams[j]) >= 0) continue;
inheritList.push(parentParams[j]);
inherited[parentParams[j]] = currentParams[parentParams[j]];
}
}
return extend({}, inherited, newParams);
}

function inherit(parent, extra) {
return extend(new (extend(function () { }, {prototype: parent}))(), extra);
}

function onStateRegistered(callback) { stateRegisteredCallbacks.push(callback); }

mod_core.provider("uirextras_core", function() {
var core = {
internalStates: internalStates,
onStateRegistered: onStateRegistered,
forEach: forEach,
extend: extend,
isArray: isArray,
map: map,
keys: keys,
filter: filter,
filterObj: filterObj,
ancestors: ancestors,
objectKeys: objectKeys,
protoKeys: protoKeys,
arraySearch: arraySearch,
inheritParams: inheritParams,
inherit: inherit
};

angular.extend(this, core);

this.$get = function() {
return core;
};
});


})(angular);
1 change: 1 addition & 0 deletions release/modular/ct-ui-router-extras.core.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

165 changes: 165 additions & 0 deletions release/modular/ct-ui-router-extras.dsr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
(function(angular, undefined){
"use strict";
var ignoreDsr;
function resetIgnoreDsr() {
ignoreDsr = undefined;
}

// Decorate $state.transitionTo to gain access to the last transition.options variable.
// This is used to process the options.ignoreDsr option
angular.module('ct.ui.router.extras.dsr', [ 'ct.ui.router.extras.core' ]).config([ "$provide", function ($provide) {
var $state_transitionTo;
$provide.decorator("$state", ['$delegate', '$q', function ($state, $q) {
$state_transitionTo = $state.transitionTo;
$state.transitionTo = function (to, toParams, options) {
if (options.ignoreDsr) {
ignoreDsr = options.ignoreDsr;
}

return $state_transitionTo.apply($state, arguments).then(
function (result) {
resetIgnoreDsr();
return result;
},
function (err) {
resetIgnoreDsr();
return $q.reject(err);
}
);
};
return $state;
}]);
}]);

angular.module('ct.ui.router.extras.dsr').service("$deepStateRedirect", [ '$rootScope', '$state', '$injector', function ($rootScope, $state, $injector) {
var lastSubstate = {};
var deepStateRedirectsByName = {};

var REDIRECT = "Redirect", ANCESTOR_REDIRECT = "AncestorRedirect";

function computeDeepStateStatus(state) {
var name = state.name;
if (deepStateRedirectsByName.hasOwnProperty(name))
return deepStateRedirectsByName[name];
recordDeepStateRedirectStatus(name);
}

function getConfig(state) {
var declaration = state.deepStateRedirect || state.dsr;
if (!declaration) return { dsr: false };
var dsrCfg = { dsr: true };

if (angular.isFunction(declaration)) {
dsrCfg.fn = declaration;
} else if (angular.isObject(declaration)) {
dsrCfg = angular.extend(dsrCfg, declaration);
}

if (angular.isString(dsrCfg.default)) {
dsrCfg.default = { state: dsrCfg.default };
}

if (!dsrCfg.fn) {
dsrCfg.fn = [ '$dsr$', function($dsr$) {
return $dsr$.redirect.state != $dsr$.to.state;
} ];
}
return dsrCfg;
}

function recordDeepStateRedirectStatus(stateName) {
var state = $state.get(stateName);
if (!state) return false;
var cfg = getConfig(state);
if (cfg.dsr) {
deepStateRedirectsByName[state.name] = REDIRECT;
if (lastSubstate[stateName] === undefined)
lastSubstate[stateName] = {};
}

var parent = state.$$state && state.$$state().parent;
if (parent) {
var parentStatus = recordDeepStateRedirectStatus(parent.self.name);
if (parentStatus && deepStateRedirectsByName[state.name] === undefined) {
deepStateRedirectsByName[state.name] = ANCESTOR_REDIRECT;
}
}
return deepStateRedirectsByName[state.name] || false;
}

function getMatchParams(params, dsrParams) {
if (dsrParams === true) dsrParams = Object.keys(params);
if (dsrParams === null || dsrParams === undefined) dsrParams = [];

var matchParams = {};
angular.forEach(dsrParams.sort(), function(name) { matchParams[name] = params[name]; });
return matchParams;
}

function getParamsString(params, dsrParams) {
var matchParams = getMatchParams(params, dsrParams);
function safeString(input) { return !input ? input : input.toString(); }
var paramsToString = {};
angular.forEach(matchParams, function(val, name) { paramsToString[name] = safeString(val); });
return angular.toJson(paramsToString);
}

$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
var cfg = getConfig(toState);
if (ignoreDsr || (computeDeepStateStatus(toState) !== REDIRECT) && !cfg.default) return;
// We're changing directly to one of the redirect (tab) states.
// Get the DSR key for this state by calculating the DSRParams option
var key = getParamsString(toParams, cfg.params);
var redirect = lastSubstate[toState.name][key] || cfg.default;
if (!redirect) return;

// we have a last substate recorded
var $dsr$ = { redirect: { state: redirect.state, params: redirect.params}, to: { state: toState.name, params: toParams } };
var result = $injector.invoke(cfg.fn, toState, { $dsr$: $dsr$ });
if (!result) return;
if (result.state) redirect = result;
event.preventDefault();
var redirectParams = getMatchParams(toParams, cfg.params);
$state.go(redirect.state, angular.extend(redirectParams, redirect.params));
});

$rootScope.$on("$stateChangeSuccess", function (event, toState, toParams, fromState, fromParams) {
var deepStateStatus = computeDeepStateStatus(toState);
if (deepStateStatus) {
var name = toState.name;
angular.forEach(lastSubstate, function (redirect, dsrState) {
// update Last-SubState&params for each DSR that this transition matches.
var cfg = getConfig($state.get(dsrState));
var key = getParamsString(toParams, cfg.params);
if (name == dsrState || name.indexOf(dsrState + ".") != -1) {
lastSubstate[dsrState][key] = { state: name, params: angular.copy(toParams) };
}
});
}
});

return {
reset: function(stateOrName, params) {
if (!stateOrName) {
angular.forEach(lastSubstate, function(redirect, dsrState) { lastSubstate[dsrState] = {}; });
} else {
var state = $state.get(stateOrName);
if (!state) throw new Error("Unknown state: " + stateOrName);
if (lastSubstate[state.name]) {
if (params) {
var key = getParamsString(params, getConfig(state).params);
delete lastSubstate[state.name][key];
} else {
lastSubstate[state.name] = {};
}
}
}
}
};
}]);

angular.module('ct.ui.router.extras.dsr').run(['$deepStateRedirect', function ($deepStateRedirect) {
// Make sure $deepStateRedirect is instantiated
}]);

})(angular);
1 change: 1 addition & 0 deletions release/modular/ct-ui-router-extras.dsr.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b6db4cf

Please sign in to comment.