Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 73 additions & 80 deletions require.intellisense.js
Original file line number Diff line number Diff line change
@@ -1,91 +1,84 @@
/// <reference path="require.js" />

!function (window) {
var defines = [],
moduleUrls = [],
oldDefine = window.define,
oldRequire = window.require,
oldLoad = requirejs.load;
(function () {
var DEBUG = 3, WARN = 2, ERROR = 1, NONE = 0;

var loadEvent = document.createEvent("event");
loadEvent.type = "load";
//Set the logging level
var logLevel = DEBUG;

// Ensure that we're only patching require/define
// if RequireJS is the current AMD implementation
if (window.require !== window.requirejs)
return;

intellisense.annotate(window, {
define: function () {
/// <signature>
/// <summary>Defines a named module, with optional dependencies, whose value is determined by executing a callback.</summary>
/// <param name="name" type="String">The name of the module</param>
/// <param name="deps" type="Array" elementType="String" optional="true">An array of modules that this module depends on</param>
/// <param name="callback" type="Function">The callback that will be called when your module is asked to produce a value</param>
/// </signature>
/// <signature>
/// <summary>Defines an anonymous module, with no dependencies, whose value is determined by executing a callback.</summary>
/// <param name="callback" type="Function">The callback that will be called when your module is asked to produce a value</param>
/// </signature>
/// <signature>
/// <summary>Defines an anonymous module, with no dependencies, whose value is an object literal.</summary>
/// <param name="value" type="Object">The object literal that represents the value of this module</param>
/// </signature>
},
require: function () {
/// <signature>
/// <summary>Defines a callback function that will be triggered after a set of dependency modules have been evaluated</summary>
/// <param name="deps" type="Array" elementType="String"></param>
/// <param name="callback" type="Function"></param>
/// </signature>
}
});

requirejs.load = function (context, moduleName, url) {
moduleUrls.push(url);
oldLoad.call(requirejs, context, moduleName, url);
function log(level) {
var msg = Array.prototype.slice.call(arguments, 1);
if (logLevel >= level) {
msg.splice(0, 0, level == DEBUG ? 'DEBUG' : level == WARN ?
'WARN' : level == ERROR ? 'ERROR' : 'UNKNOWN');
intellisense.logMessage(msg.join(':'));
}
}

window.define = function (name, deps, callback) {
defines.push([name, deps, callback]);
log(DEBUG, "Re-read _references.js ");

oldRequire.call(window, deps, callback);

defines.forEach(function (define) {
oldDefine.apply(window, define);
});
//Redirect errors to intellisense log
requirejs.onError = function (e) {
var modules = e.requireModules && e.requireModules.join(',');
switch (e.requireType) {
case 'scripterror':
log(WARN, modules, "Dependency script not yet loaded, check the stated define name matches the require.");
break;
default:
log(ERROR, e.requireType, modules, e.toString());
break;
}

window.define.amd = {
multiversion: true,
plugins: true,
jQuery: true
};

window.require = function (deps, callback) {
setTimeout(function () {
// #1. Call the original require
oldRequire.call(window, deps, callback);

defines.forEach(function (define, index) {
oldDefine.apply(window, define);
};

var scriptElements = document.getElementsByTagName("script");

for (var i = 0; i < scriptElements.length; i++) {
var script = scriptElements[i];
if (script.src == moduleUrls[index]) {
loadEvent.currentTarget = script;
requirejs.onScriptLoad(loadEvent);
}
}
});
}, 0);
var originalDefine = define;
var lastDefine;
var currentDocumentId = "_@ROOT";
define = function (name, deps, callback) {
//Disallow anonymous modules - unfortunately we can't handle them
//without turning everything to guesswork.
if (typeof name !== 'string') {
log(ERROR, "Intellisense not supported for anonymous modules");
}
//Make use of the fact that VS seemingly invokes the current document
//code twice. On the second call, rename the module to ensure this
//specific code will be evaluated and then require it to evaluate it.
if (lastDefine === name) {
log(DEBUG, "Define current document");
originalDefine(currentDocumentId, deps, callback);
log(DEBUG, "Require current document");
require([currentDocumentId], function () {
//This log message may never get printed as VS stops execution of
//the current document once it hits the node at which auto-
//completion has being invoked.
log(DEBUG, "Loaded current document and all dependencies");
});
} else {
log(DEBUG, "Define module", name);
originalDefine(name, deps, callback);
}
lastDefine = name;
};

// Redirect all of the patched methods back to their originals
// so Intellisense will use the previously defined annotations
intellisense.redirectDefinition(requirejs.load, oldLoad);
intellisense.redirectDefinition(window.define, oldDefine);
intellisense.redirectDefinition(window.require, oldRequire);
}(this);
intellisense.annotate(window, {
define: function () {
/// <signature>
/// <summary>Defines a named module, with optional dependencies, whose value is determined by executing a callback.</summary>
/// <param name="name" type="String">The name of the module</param>
/// <param name="deps" type="Array" elementType="String" optional="true">An array of modules that this module depends on</param>
/// <param name="callback" type="Function">The callback that will be called when your module is asked to produce a value</param>
/// </signature>
/// <signature>
/// <summary>Defines a named module, with optional dependencies, whose value is determined by executing a callback.</summary>
/// <param name="name" type="String">The name of the module</param>
/// <param name="callback" type="Function">The callback that will be called when your module is asked to produce a value</param>
/// </signature>
},
require: function () {
/// <signature>
/// <summary>Defines a callback function that will be triggered after a set of dependency modules have been evaluated</summary>
/// <param name="deps" type="Array" elementType="String"></param>
/// <param name="callback" type="Function"></param>
/// </signature>
}
});
}());