Skip to content

Commit

Permalink
Move utility functions to NGI.Utils, also including an annotate imple…
Browse files Browse the repository at this point in the history
…mentation
  • Loading branch information
rev087 committed Apr 15, 2015
1 parent 9b35153 commit 103ea50
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 133 deletions.
1 change: 1 addition & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ gulp.task('build:js', function() {
'src/js/InspectorPane.js',
'src/js/TreeView.js',
'src/js/Highlighter.js',
'src/js/Utils.js',
'src/js/Service.js',
'src/js/App.js',
'src/js/Module.js',
Expand Down
111 changes: 81 additions & 30 deletions ng-inspector.chrome/ng-inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,29 @@ NGI.Highlighter = (function() {
/* jshint strict: false */
/* jshint shadow: true */

NGI.Service = (function() {
NGI.Utils = (function() {

var Utils = {};

var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;

/**
* Converts snake_case to camelCase.
* Also a special case for Moz prefix starting with upper case letter.
*/
Utils.camelCase = function(name) {
return name.
replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).
replace(MOZ_HACK_REGEXP, 'Moz$1');
}

var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;

var PREFIX_REGEXP = /^(x[\:\-_]|data[\:\-_])/i;
/**
Expand All @@ -701,26 +723,58 @@ NGI.Service = (function() {
* x-my-directive
* data-my:directive
*/
function directiveNormalize(name) {
return camelCase(name.replace(PREFIX_REGEXP, ''));
Utils.directiveNormalize = function(name) {
return NGI.Utils.camelCase(name.replace(PREFIX_REGEXP, ''));
}

var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;

/**
* Converts snake_case to camelCase.
* Also there is special case for Moz prefix starting with upper case letter.
* @param name Name to normalize
*/
function camelCase(name) {
return name.
replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).
replace(MOZ_HACK_REGEXP, 'Moz$1');
* Receives a function and returns an array of strings representing the
* function arguments.
*
* Adapted from https://github.com/angular/angular.js/blob/0baa17a3b7ad2b242df2b277b81cebdf75b04287/src/auto/injector.js
**/
Utils.annotate = function(fn) {
var $inject,
fnText,
argDecl,
last;

if (typeof fn === 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
if (fn.length) {
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
var argDecls = argDecl[1].split(FN_ARG_SPLIT);
for (var i = 0; i < argDecls.length; i++) {
var arg = argDecls[i];
arg.replace(FN_ARG, function(all, underscore, name) {
$inject.push(name);
});
};
}
fn.$inject = $inject;
}
} else if (isArray(fn)) {
last = fn.length - 1;
assertArgFn(fn[last], 'fn');
$inject = fn.slice(0, last);
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}

return Utils;

})();

/* global NGI */
/* jshint strict: false */
/* jshint shadow: true */

NGI.Service = (function() {

var CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/;

function Service(app, module, invoke) {
Expand All @@ -737,16 +791,13 @@ NGI.Service = (function() {
// If $injector.annotate is available in the user's version of Angular we
// attempt to salvage it, otherwise return and ignore the directive.
if (Object.prototype.toString.call(this.factory) !== '[object Array]') {
if (app.$injector.annotate) {
var annotated = app.$injector.annotate(this.factory);
annotated.push(this.factory);
this.factory = annotated;
} else {
return;
}
var annotation = NGI.Utils.annotate(this.factory);
annotation.push(this.factory);
this.factory = annotation;
}
var dir = app.$injector.invoke(this.factory);
if (!dir) {
try {
var dir = app.$injector.invoke(this.factory);
} catch(e) {
console.warn(
'Invalid directive "' + (this.name || '(unknown)') +
'" found. Make sure all registered directives ' +
Expand All @@ -768,7 +819,7 @@ NGI.Service = (function() {
if (restrict.indexOf('A') > -1 ||
(dir.replace === true && restrict.indexOf('M') > -1)) {
for (var i = 0; i < node.attributes.length; i++) {
var normalized = directiveNormalize(node.attributes[i].name);
var normalized = NGI.Utils.directiveNormalize(node.attributes[i].name);
if (normalized === name) {
if (!isIsolate && dir.scope === true ||
isIsolate && typeof dir.scope === typeof {}) {
Expand All @@ -780,7 +831,7 @@ NGI.Service = (function() {

// Test for Element directives
if (restrict.indexOf('E') > -1) {
var normalized = directiveNormalize(node.tagName.toLowerCase());
var normalized = NGI.Utils.directiveNormalize(node.tagName.toLowerCase());
if (normalized === name) {
if (!isIsolate && dir.scope === true ||
isIsolate && typeof dir.scope === typeof {}) {
Expand All @@ -795,7 +846,7 @@ NGI.Service = (function() {
if (matches) {
for (var i = 0; i < matches.length; i++) {
if (!matches[i]) continue;
var normalized = directiveNormalize(matches[i]);
var normalized = NGI.Utils.directiveNormalize(matches[i]);
if (normalized === name) {
if (!isIsolate && dir.scope === true ||
isIsolate && typeof dir.scope === typeof {}) {
Expand All @@ -818,7 +869,7 @@ NGI.Service = (function() {

// Test for the presence of the ngController directive
for (var i = 0; i < node.attributes.length; i++) {
var normalized = directiveNormalize(node.attributes[i].name);
var normalized = NGI.Utils.directiveNormalize(node.attributes[i].name);
if (normalized === 'ngController') {
scope.view.addAnnotation(node.attributes[i].value, Service.CTRL);
}
Expand Down Expand Up @@ -1335,7 +1386,7 @@ NGI.Model = (function() {
// Function
else if (angular.isFunction(value)) {
this.view.setType('ngi-model-function');
var args = angular.injector().annotate(value).join(', ');
var args = NGI.Utils.annotate(value).join(', ');
valSpan.innerText = 'function(' + args + ') {...}';
}

Expand Down
111 changes: 81 additions & 30 deletions ng-inspector.safariextension/ng-inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,29 @@ NGI.Highlighter = (function() {
/* jshint strict: false */
/* jshint shadow: true */

NGI.Service = (function() {
NGI.Utils = (function() {

var Utils = {};

var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;

/**
* Converts snake_case to camelCase.
* Also a special case for Moz prefix starting with upper case letter.
*/
Utils.camelCase = function(name) {
return name.
replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).
replace(MOZ_HACK_REGEXP, 'Moz$1');
}

var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;

var PREFIX_REGEXP = /^(x[\:\-_]|data[\:\-_])/i;
/**
Expand All @@ -701,26 +723,58 @@ NGI.Service = (function() {
* x-my-directive
* data-my:directive
*/
function directiveNormalize(name) {
return camelCase(name.replace(PREFIX_REGEXP, ''));
Utils.directiveNormalize = function(name) {
return NGI.Utils.camelCase(name.replace(PREFIX_REGEXP, ''));
}

var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;

/**
* Converts snake_case to camelCase.
* Also there is special case for Moz prefix starting with upper case letter.
* @param name Name to normalize
*/
function camelCase(name) {
return name.
replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).
replace(MOZ_HACK_REGEXP, 'Moz$1');
* Receives a function and returns an array of strings representing the
* function arguments.
*
* Adapted from https://github.com/angular/angular.js/blob/0baa17a3b7ad2b242df2b277b81cebdf75b04287/src/auto/injector.js
**/
Utils.annotate = function(fn) {
var $inject,
fnText,
argDecl,
last;

if (typeof fn === 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
if (fn.length) {
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
var argDecls = argDecl[1].split(FN_ARG_SPLIT);
for (var i = 0; i < argDecls.length; i++) {
var arg = argDecls[i];
arg.replace(FN_ARG, function(all, underscore, name) {
$inject.push(name);
});
};
}
fn.$inject = $inject;
}
} else if (isArray(fn)) {
last = fn.length - 1;
assertArgFn(fn[last], 'fn');
$inject = fn.slice(0, last);
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}

return Utils;

})();

/* global NGI */
/* jshint strict: false */
/* jshint shadow: true */

NGI.Service = (function() {

var CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/;

function Service(app, module, invoke) {
Expand All @@ -737,16 +791,13 @@ NGI.Service = (function() {
// If $injector.annotate is available in the user's version of Angular we
// attempt to salvage it, otherwise return and ignore the directive.
if (Object.prototype.toString.call(this.factory) !== '[object Array]') {
if (app.$injector.annotate) {
var annotated = app.$injector.annotate(this.factory);
annotated.push(this.factory);
this.factory = annotated;
} else {
return;
}
var annotation = NGI.Utils.annotate(this.factory);
annotation.push(this.factory);
this.factory = annotation;
}
var dir = app.$injector.invoke(this.factory);
if (!dir) {
try {
var dir = app.$injector.invoke(this.factory);
} catch(e) {
console.warn(
'Invalid directive "' + (this.name || '(unknown)') +
'" found. Make sure all registered directives ' +
Expand All @@ -768,7 +819,7 @@ NGI.Service = (function() {
if (restrict.indexOf('A') > -1 ||
(dir.replace === true && restrict.indexOf('M') > -1)) {
for (var i = 0; i < node.attributes.length; i++) {
var normalized = directiveNormalize(node.attributes[i].name);
var normalized = NGI.Utils.directiveNormalize(node.attributes[i].name);
if (normalized === name) {
if (!isIsolate && dir.scope === true ||
isIsolate && typeof dir.scope === typeof {}) {
Expand All @@ -780,7 +831,7 @@ NGI.Service = (function() {

// Test for Element directives
if (restrict.indexOf('E') > -1) {
var normalized = directiveNormalize(node.tagName.toLowerCase());
var normalized = NGI.Utils.directiveNormalize(node.tagName.toLowerCase());
if (normalized === name) {
if (!isIsolate && dir.scope === true ||
isIsolate && typeof dir.scope === typeof {}) {
Expand All @@ -795,7 +846,7 @@ NGI.Service = (function() {
if (matches) {
for (var i = 0; i < matches.length; i++) {
if (!matches[i]) continue;
var normalized = directiveNormalize(matches[i]);
var normalized = NGI.Utils.directiveNormalize(matches[i]);
if (normalized === name) {
if (!isIsolate && dir.scope === true ||
isIsolate && typeof dir.scope === typeof {}) {
Expand All @@ -818,7 +869,7 @@ NGI.Service = (function() {

// Test for the presence of the ngController directive
for (var i = 0; i < node.attributes.length; i++) {
var normalized = directiveNormalize(node.attributes[i].name);
var normalized = NGI.Utils.directiveNormalize(node.attributes[i].name);
if (normalized === 'ngController') {
scope.view.addAnnotation(node.attributes[i].value, Service.CTRL);
}
Expand Down Expand Up @@ -1335,7 +1386,7 @@ NGI.Model = (function() {
// Function
else if (angular.isFunction(value)) {
this.view.setType('ngi-model-function');
var args = angular.injector().annotate(value).join(', ');
var args = NGI.Utils.annotate(value).join(', ');
valSpan.innerText = 'function(' + args + ') {...}';
}

Expand Down
2 changes: 1 addition & 1 deletion src/js/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ NGI.Model = (function() {
// Function
else if (angular.isFunction(value)) {
this.view.setType('ngi-model-function');
var args = angular.injector().annotate(value).join(', ');
var args = NGI.Utils.annotate(value).join(', ');
valSpan.innerText = 'function(' + args + ') {...}';
}

Expand Down
Loading

0 comments on commit 103ea50

Please sign in to comment.