Skip to content
This repository was archived by the owner on Apr 4, 2025. It is now read-only.

Commit 57c18f9

Browse files
welborniobtford
authored andcommitted
refactor(modules): importing angular hint modules
1 parent 97d2df1 commit 57c18f9

22 files changed

+270
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/bower_components/
33
/node_modules/
44
/dist/
5+
/.idea/

hint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require('./src/modules/controllers');
99
// require('./src/modules/dom');
1010
require('./src/modules/events');
1111
// require('./src/modules/interpolation');
12-
// require('./src/modules/modules');
12+
require('./src/modules/modules');
1313
require('./src/modules/scopes');
1414

1515
// List of all possible modules

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"protractor": "^1.5.0",
4949
"routes-router": "^4.1.1",
5050
"st": "^0.5.2",
51+
"suggest-it": "0.0.1",
5152
"vinyl-source-stream": "^1.0.0"
5253
}
5354
}

src/modules/display.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
var hintLog = angular.hint = require('./log'),
2+
MODULE_NAME = 'Modules';
3+
4+
module.exports = function(modules) {
5+
modules.forEach(function(module) {
6+
hintLog.logMessage(MODULE_NAME, module.message, module.severity);
7+
});
8+
};

src/modules/formatMultiLoaded.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var modData = require('./moduleData');
2+
MODULE_NAME = 'Modules',
3+
SEVERITY_WARNING = 2;
4+
5+
module.exports = function() {
6+
var multiLoaded = [];
7+
for(var modName in modData.createdMulti) {
8+
var message = 'Multiple modules with name "' + modName + '" are being created and they will ' +
9+
'overwrite each other.';
10+
var multi = modData.createdMulti[modName];
11+
var multiLength = multi.length;
12+
var details = {
13+
existingModule: multi[multiLength - 1],
14+
overwrittenModules: multi.slice(0, multiLength - 1)
15+
};
16+
multiLoaded
17+
.push({module: details, message: message, name: MODULE_NAME, severity: SEVERITY_WARNING});
18+
}
19+
return multiLoaded;
20+
};

src/modules/getModule.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var modData = require('./moduleData');
2+
3+
module.exports = function(moduleName, getCreated) {
4+
return (getCreated)? modData.createdModules[moduleName] : modData.loadedModules[moduleName];
5+
};

src/modules/getNgAppMod.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var hintLog = angular.hint = require('./log'),
2+
MODULE_NAME = 'Modules',
3+
SEVERITY_ERROR = 1;
4+
module.exports = function(attrs, ngAppFound) {
5+
if(attrs['ng-app'] && ngAppFound) {
6+
hintLog.logMessage(MODULE_NAME, 'ng-app may only be included once. The module "' +
7+
attrs['ng-app'].value + '" was not used to bootstrap because ng-app was already included.',
8+
SEVERITY_ERROR);
9+
}
10+
return attrs['ng-app'] ? attrs['ng-app'].value : undefined;
11+
};
12+
13+

src/modules/getUndeclaredModules.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var getModule = require('./getModule'),
2+
dictionary = Object.keys(require('./moduleData').createdModules),
3+
suggest = require('suggest-it')(dictionary),
4+
SEVERITY_ERROR = 1;
5+
6+
module.exports = function(loadedModules) {
7+
var undeclaredModules = [];
8+
for(var module in loadedModules) {
9+
var cModule = getModule(module, true);
10+
if(!cModule) {
11+
var match = suggest(module),
12+
suggestion = (match) ? '; Try: "'+match+'"' : '',
13+
message = 'Module "'+module+'" was loaded but does not exist'+suggestion+'.';
14+
15+
undeclaredModules.push({module: null, message: message, severity: SEVERITY_ERROR});
16+
}
17+
}
18+
return undeclaredModules;
19+
};

src/modules/getUnusedModules.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var getModule = require('./getModule');
2+
3+
var IGNORED = ['ngHintControllers', 'ngHintDirectives', 'ngHintDom', 'ngHintEvents',
4+
'ngHintInterpolation', 'ngHintModules', 'ngHintScopes', 'ng', 'ngLocale', 'protractorBaseModule_'],
5+
SEVERITY_WARNING = 2;
6+
7+
module.exports = function(createdModules) {
8+
var unusedModules = [];
9+
for(var module in createdModules) {
10+
if(!getModule(module)) {
11+
var cModule = createdModules[module],
12+
message = 'Module "' + cModule.name + '" was created but never loaded.';
13+
if(IGNORED.indexOf(cModule.name) === -1) {
14+
unusedModules.push({module: cModule, message: message, severity: SEVERITY_WARNING});
15+
}
16+
}
17+
}
18+
return unusedModules;
19+
};

src/modules/hasNameSpace.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var hintLog = angular.hint = require('./log'),
2+
MODULE_NAME = 'Modules',
3+
SEVERITY_SUGGESTION = 3;
4+
5+
module.exports = function(str) {
6+
if (str === 'ng') {
7+
return true;
8+
}
9+
10+
if(str.toLowerCase() === str || str.charAt(0).toUpperCase() === str.charAt(0)) {
11+
hintLog.log(MODULE_NAME, 'The best practice for' +
12+
' module names is to use lowerCamelCase. Check the name of "' + str + '".',
13+
SEVERITY_SUGGESTION);
14+
return false;
15+
}
16+
return true;
17+
};

src/modules/hint-log.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict';
2+
3+
/*
4+
* HintLog creates a queue of messages logged by ngHint modules. This object
5+
* has a key for each ngHint module that corresponds to the messages
6+
* from that module.
7+
*/
8+
var queuedMessages = {},
9+
MESSAGE_TYPES = [
10+
'error',
11+
'warning',
12+
'suggestion'
13+
];
14+
15+
/*
16+
* Add a message to the HintLog message queue. Messages are organized into categories
17+
* according to their module name and severity.
18+
*/
19+
function logMessage(moduleName, message, severity, category) {
20+
// If no severity was provided, categorize the message as a `suggestion`
21+
severity = severity || 3;
22+
var messageType = MESSAGE_TYPES[severity - 1];
23+
24+
moduleName = moduleName || 'General';
25+
26+
// If the category does not exist, initialize a new object
27+
queuedMessages[moduleName] = queuedMessages[moduleName] || {};
28+
queuedMessages[moduleName][messageType] = queuedMessages[moduleName][messageType] || [];
29+
30+
if (queuedMessages[moduleName][messageType].indexOf(message) < 0) {
31+
queuedMessages[moduleName][messageType].push(message);
32+
}
33+
34+
this.onMessage(moduleName, message, messageType, category);
35+
}
36+
37+
/*
38+
* Return and empty the current queue of messages.
39+
*/
40+
function flush() {
41+
var flushMessages = queuedMessages;
42+
queuedMessages = {};
43+
return flushMessages;
44+
}
45+
46+
module.exports.onMessage = function(message) {};
47+
module.exports.logMessage = logMessage;
48+
module.exports.flush = flush;

src/modules/inAttrsOrClasses.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var normalizeAttribute = require('./normalizeAttribute');
2+
3+
module.exports = function(attrs) {
4+
for(var i = 0, length = attrs.length; i < length; i++) {
5+
if(normalizeAttribute(attrs[i].nodeName) === 'ng-view' ||
6+
attrs[i].value.indexOf('ng-view') > -1) {
7+
return true;
8+
}
9+
}
10+
};

src/modules/log.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,5 @@ function flush() {
4949
angular.hint.onMessage = function(message) {};
5050
angular.hint.log = logMessage;
5151
angular.hint.flush = flush;
52+
53+
module.exports = angular.hint;

src/modules/moduleData.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
createdModules: {},
3+
createdMulti: {},
4+
loadedModules: {}
5+
};

src/modules/modules.xjs renamed to src/modules/modules.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use strict';
22

3-
var getModule = require('./src/getModule'),
4-
start = require('./src/start'),
5-
storeNgAppAndView = require('./src/storeNgAppAndView'),
6-
storeUsedModules = require('./src/storeUsedModules'),
7-
hasNameSpace = require('./src/hasNameSpace'),
8-
modData = require('./src/moduleData');
3+
var getModule = require('./getModule'),
4+
start = require('./start'),
5+
storeNgAppAndView = require('./storeNgAppAndView'),
6+
storeUsedModules = require('./storeUsedModules'),
7+
hasNameSpace = require('./hasNameSpace'),
8+
modData = require('./moduleData');
99

1010
var doc = Array.prototype.slice.call(document.getElementsByTagName('*')),
1111
originalAngularModule = angular.module,
@@ -19,7 +19,7 @@ angular.module = function(name, requiresOriginal) {
1919

2020
module.requiresOriginal = requiresOriginal;
2121
modules[name] = module;
22-
hasNameSpace(module);
22+
hasNameSpace(name);
2323
var modToCheck = getModule(name, true);
2424

2525
if(modToCheck && modToCheck.requiresOriginal !== module.requiresOriginal) {

src/modules/ngViewNoNgRoute.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
var modData = require('./moduleData'),
2+
getModule = require('./getModule');
3+
4+
module.exports = function() {
5+
if(modData.ngViewExists && !getModule('ngRoute')) {
6+
return {message: 'Directive "ngView" was used in the application however "ngRoute" was not loaded into any module.'};
7+
}
8+
};

src/modules/normalizeAttribute.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function(attribute) {
2+
return attribute.replace(/^(?:data|x)[-_:]/, '').replace(/[:_]/g, '-');
3+
};

src/modules/start.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
var display = require('./display'),
2+
formatMultiLoaded = require('./formatMultiLoaded'),
3+
getUnusedModules = require('./getUnusedModules'),
4+
getUndeclaredModules = require('./getUndeclaredModules'),
5+
modData = require('./moduleData'),
6+
ngViewNoNgRoute = require('./ngViewNoNgRoute');
7+
8+
module.exports = function() {
9+
var unusedModules = getUnusedModules(modData.createdModules),
10+
undeclaredModules = getUndeclaredModules(modData.loadedModules),
11+
multiLoaded = formatMultiLoaded(),
12+
noNgRoute = ngViewNoNgRoute();
13+
if(unusedModules.length || undeclaredModules.length || multiLoaded.length || noNgRoute) {
14+
var toSend = unusedModules.concat(undeclaredModules)
15+
.concat(multiLoaded);
16+
if(noNgRoute) {
17+
toSend = toSend.concat(noNgRoute);
18+
}
19+
display(toSend);
20+
}
21+
};

src/modules/storeDependencies.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var modData = require('./moduleData');
2+
3+
module.exports = function(module, isNgAppMod) {
4+
var name = module.name || module;
5+
if(!isNgAppMod){
6+
module.requires.forEach(function(dependency){
7+
modData.loadedModules[dependency] = dependency;
8+
});
9+
}
10+
else {
11+
modData.loadedModules[name] = name;
12+
modData.ngAppMod = name;
13+
}
14+
};

src/modules/storeNgAppAndView.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
var getNgAppMod = require('./getNgAppMod'),
2+
inAttrsOrClasses = require('./inAttrsOrClasses'),
3+
storeDependencies = require('./storeDependencies'),
4+
modData = require('./moduleData');
5+
6+
module.exports = function(doms) {
7+
var bothFound,
8+
ngViewFound,
9+
elem,
10+
isElemName,
11+
isInAttrsOrClasses,
12+
ngAppMod;
13+
14+
for(var i = 0; i < doms.length; i++) {
15+
elem = doms[i];
16+
var attributes = elem.attributes;
17+
isElemName = elem.nodeName.toLowerCase() === 'ng-view';
18+
isInAttrsOrClasses = inAttrsOrClasses(attributes);
19+
20+
ngViewFound = isElemName || isInAttrsOrClasses;
21+
22+
ngAppMod = getNgAppMod(attributes, modData.ngAppFound);
23+
modData.ngAppFound = modData.ngAppFound || ngAppMod;
24+
25+
if(ngAppMod) {
26+
storeDependencies(ngAppMod, true);
27+
}
28+
modData.ngViewExists = ngViewFound ? true : modData.ngViewExists;
29+
30+
if(bothFound) {
31+
break;
32+
}
33+
}
34+
};

src/modules/storeUsedModules.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
var storeDependencies = require('./storeDependencies');
2+
3+
var storeUsedModules = module.exports = function(module, modules){
4+
if(module) {
5+
storeDependencies(module);
6+
module.requires.forEach(function(modName) {
7+
var mod = modules[modName];
8+
storeUsedModules(mod, modules);
9+
});
10+
}
11+
};

test/controllers.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,17 @@ describe('module.controller', function() {
246246
});
247247

248248
it('should accept name and constructor as separate arguments', function() {
249-
angular.module('SampleApp', []).controller('SampleController', angular.noop);
249+
angular.module('sampleApp', []).controller('SampleController', angular.noop);
250250
expect(angular.hint.log).not.toHaveBeenCalled();
251251

252-
angular.module('SampleApp', []).controller('sampleController', angular.noop);
252+
angular.module('sampleApp', []).controller('sampleController', angular.noop);
253253
expect(angular.hint.log).toHaveBeenCalled();
254254
expect(angular.hint.log.calls.count()).toBe(1);
255255
});
256256

257257

258258
it('should accept a map of name/constructor pairs', function() {
259-
angular.module('SampleApp', []).controller({
259+
angular.module('sampleApp', []).controller({
260260
'SampleController': angular.noop,
261261
'sampleController': angular.noop
262262
});

0 commit comments

Comments
 (0)