Skip to content

Commit

Permalink
Minor bug fixes and upgrading uxGenie
Browse files Browse the repository at this point in the history
  • Loading branch information
Kent C. Dodds committed Dec 30, 2013
1 parent e259c2a commit 683281d
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 41 deletions.
186 changes: 160 additions & 26 deletions demo-files/vendor/uxGenie.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
uxGenie.constant('genie', genie);

uxGenie.directive('uxLamp', ['genie', '$timeout', '$document', function(genie, $timeout, $document) {
var states = {
userEntry: 'userentry',
subContext: 'subcontext'
}
return {
replace: true,
template: function(el, attr) {
Expand All @@ -28,7 +32,7 @@
return ['<div class="genie-container"' + ngShow + '>',
'<input type="text" ng-model="genieInput" class="lamp-input input form-control" />',
'<div ng-show="matchingWishes.length > 0" class="genie-wishes">',
'<div class="genie-wish" ' +
'<div class="genie-wish wish-{{wish.id}}" ' +
'ng-repeat="wish in matchingWishes" ' +
'ng-class="{focused: focusedWish == wish}" ' +
'ng-click="makeWish(wish)" ' +
Expand All @@ -39,15 +43,20 @@
'</div></div></div>'].join('');
},
scope: {
lampVisible: '=',
lampVisible: '=?',
rubClass: '@',
rubShortcut: '@',
rubModifier: '@',
rubEventType: '@',
wishCallback: '&',
localStorage: '='
wishCallback: '&?',
localStorage: '=?'
},
link: function(scope, el, attr) {
scope.genieInput = '';
scope.state = states.userEntry;

var mathResultId = 'ux-genie-math-result';
var startTextForSubContext = null;
var inputEl = angular.element(el.children()[0]);
var genieOptionContainer = angular.element(el.children()[1]);
var rubShortcut = scope.rubShortcut || '32';
Expand All @@ -70,7 +79,7 @@
// Wish focus
scope.focusOnWish = function(wishElement, autoScroll) {
scope.focusedWish = wishElement;
if (autoScroll) {
if (scope.focusedWish && autoScroll) {
scrollToWish(scope.matchingWishes.indexOf(wishElement));
}
};
Expand Down Expand Up @@ -172,14 +181,57 @@
}
})());

function _setSubContextState(wish) {
if (scope.state !== states.subContext) {
scope.state = states.subContext;
startTextForSubContext = wish.magicWords[0] + ' ';
if (wish.data && wish.data.uxGenie && wish.data.uxGenie.displayText) {
startTextForSubContext = wish.data.uxGenie.displayText;
}
genie.context(wish.data.uxGenie.subContext);
scope.$apply(function() {
scope.genieInput = startTextForSubContext;
});
}
}

function _exitSubContext() {
genie.revertContext();
scope.state = states.userEntry;
startTextForSubContext = null;
}

// Making a wish
scope.makeWish = function(wish) {
scope.wishCallback(genie.makeWish(wish, scope.genieInput));
saveToLocalStorage(wish);
scope.$apply(function() {
scope.lampVisible = false;
var makeWish = true;
var makeInvisible = true;
if (wish.id === mathResultId) {
makeWish = false;
}

if (_isSubContextWish(wish)) {
_setSubContextState(wish);
makeInvisible = false;
if (!wish.action) {
makeWish = false;
}
}

if (makeWish) {
wish = genie.makeWish(wish, scope.genieInput);
saveToLocalStorage(wish);
}

scope.wishCallback({
wish: wish,
magicWord: scope.genieInput
});
}
if (makeInvisible) {
scope.$apply(function() {
scope.lampVisible = false;
});
}
};

el.bind('keyup', function(event) {
if (event.keyCode === 13 && scope.focusedWish) {
Expand All @@ -205,21 +257,67 @@
}
}

if (scope.rubClass) {
scope.$watch('lampVisible', function(newVal) {
if (newVal) {
updateMatchingWishes(scope.genieInput);
function handleInputChange(newVal) {
if (scope.state === states.subContext) {
if (newVal.indexOf(startTextForSubContext.trim()) === 0) {
newVal = newVal.substring(startTextForSubContext.length);
} else {
_exitSubContext();
}
}
updateMatchingWishes(newVal);
var firstWish = null;
var firstWishDisplay = null;
if (scope.matchingWishes && scope.matchingWishes.length > 0) {
firstWish = scope.matchingWishes[0];
firstWishDisplay = firstWish.magicWords[0];
if (firstWish.data && firstWish.data.uxGenie && firstWish.data.uxGenie.displayText) {
firstWishDisplay = firstWish.data.uxGenie.displayText;
}
}

if (firstWish && scope.matchingWishes.length === 1 &&
_isSubContextWish(firstWish) && firstWishDisplay === newVal) {
_setSubContextState(firstWish);
}

var result = _evaluateMath(newVal);
if (angular.isNumber(result)) {
scope.matchingWishes = scope.matchingWishes || [];
scope.matchingWishes.unshift({
id: mathResultId,
data: {
uxGenie: {
displayText: newVal + ' = ' + result
}
}
});
scope.focusedWish = scope.matchingWishes[0];
}
}

scope.$watch('lampVisible', function(lampIsVisible) {
if (scope.state === states.subContext) {
_exitSubContext();
}
if (lampIsVisible) {
handleInputChange(scope.genieInput);
if (scope.rubClass) {
el.addClass(scope.rubClass);
// Needs to be lampVisible before it can be selected
$timeout(function() {
inputEl[0].select();
}, 25);
} else {
inputEl[0].select();
}
} else {
if (scope.rubClass) {
el.removeClass(scope.rubClass);
inputEl[0].blur();
}
});
}
inputEl[0].blur();
}
});

if (scope.localStorage && localStorage) {
// Load machine's preferences
Expand All @@ -235,9 +333,34 @@
}
}

scope.$watch('genieInput', function(newVal) {
updateMatchingWishes(newVal);
});
function _isSubContextWish(wish) {
return !!wish.data && !!wish.data.uxGenie && !!wish.data.uxGenie.subContext;
}

function _evaluateMath(expression) {
var mathRegex = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>^\\?:])/ig;
var valid = true;

expression = expression.replace(mathRegex, function (match) {
if (Math.hasOwnProperty(match)) {
return 'Math.' + match;
} else {
valid = false;
}
});

if (!valid) {
return false;
} else {
try {
return eval(expression);
} catch (e) {
return false;
}
}
}

scope.$watch('genieInput', handleInputChange);
}
}
}]);
Expand Down Expand Up @@ -286,18 +409,29 @@
magicWords = attrs[attrName];
return !magicWords;
});
magicWords = magicWords || el.text();
magicWords = magicWords.replace(/\\,/g, '{{COMMA}}');
if (magicWords) {
magicWords = magicWords.split(',');
} else {
throw new Error('Thrown by the genie-wish directive: All genie-wish elements must have a magic-words, id, or name attribute.');
}
for (var i = 0; i < magicWords.length; i++) {
magicWords[i] = magicWords[i].replace(/\{\{COMMA\}\}/g, ',');
}

genie({
id: id,
magicWords: magicWords,
context: context,
action: action,
data: data
var wishRegistered = false;
attrs.$observe('ignoreWish', function(newVal) {
if (newVal !== 'true' && !wishRegistered) {
genie({
id: id,
magicWords: magicWords,
context: context,
action: action,
data: data
});
wishRegistered = true;
}
});
}
}
Expand Down
23 changes: 10 additions & 13 deletions genie.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,20 @@
}

function _createAction(action) {
if (typeof action === 'function') { // Custom action
return action;
}

if (typeof action === 'string') { // Default nav action
action = {
destination: action
}
return function() {
if (action.openNewTab) {
window.open(action.destination, '_blank');
} else {
window.location.href = action.destination;
}
};
}

return function() {
if (action.openNewTab) {
window.open(action.destination, '_blank');
} else {
window.location.href = action.destination;
}
};

return action;
}

function deregisterWish(id) {
Expand Down Expand Up @@ -302,7 +299,7 @@
return null;
}

wish.action(wish);
wish.action && wish.action(wish, magicWord);

if (magicWord !== undefined) {
// Reset entered magicWords order.
Expand Down
Loading

0 comments on commit 683281d

Please sign in to comment.