This repository has been archived by the owner on May 25, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathmain.js
199 lines (167 loc) · 7.74 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/* https://github.com/adobe/brackets/blob/master/src/extensions/default/JavaScriptQuickEdit/main.js */
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, brackets, $ */
define(function (require, exports, module) {
"use strict";
// Brackets modules
var MultiRangeInlineEditor = brackets.getModule("editor/MultiRangeInlineEditor").MultiRangeInlineEditor,
ProjectManager = brackets.getModule("project/ProjectManager"),
EditorManager = brackets.getModule("editor/EditorManager"),
NGUtils = require("NGUtils");
var patterns = {
directive: /\.directive\(['"]([a-zA-Z-]+)['"]/g,
controller: /\.controller\(['"](\w+)['"]/g
};
/**
* Return the token string that is at the specified position.
*
* @param hostEditor {!Editor} editor
* @param {!{line:Number, ch:Number}} pos
* @return {String} token string at the specified position
*/
function _getDirectiveName(hostEditor, pos) {
var token = hostEditor._codeMirror.getTokenAt(pos, true);
// If the pos is at the beginning of a name, token will be the
// preceding whitespace or dot. In that case, try the next pos.
if (token.string.trim().length === 0 || token.string === "<") {
token = hostEditor._codeMirror.getTokenAt({line: pos.line, ch: pos.ch + 1}, true);
}
// Return valid function expressions only (function call or reference)
if (!((token.type === "tag") ||
(token.type === "attribute"))) {
return null;
}
// Trim the 'data-' prefix
if (token.string.indexOf('data-')===0) {
token.string = token.string.substr(5);
}
return token.string.replace(/\-\w/g, function(x){ return x.charAt(1).toUpperCase(); });
}
/**
* Return the token string that is at the specified position.
*
* @param hostEditor {!Editor} editor
* @param {!{line:Number, ch:Number}} pos
* @return {String} token string at the specified position
*/
function _getControllerName(hostEditor, pos) {
var token = hostEditor._codeMirror.getTokenAt(pos, true);
var attribute;
if (~token.string.indexOf("ng-controller")) {
attribute = hostEditor._codeMirror.getTokenAt({line: pos.line, ch: token.end + 2}, true);
return /\w+/i.exec(attribute.string)[0];
}
attribute = hostEditor._codeMirror.getTokenAt({line: pos.line, ch: token.start - 2}, true);
// Return valid function expressions only (function call or reference)
if (~attribute.string.indexOf("ng-controller")) {
return /\w+/i.exec(token.string)[0];
}
}
/**
* @private
* For unit and performance tests. Allows lookup by function name instead of editor offset
* without constructing an inline editor.
*
* @param {!string} directiveName
* @return {$.Promise} a promise that will be resolved with an array of function offset information
*/
function _findInProject(directiveName, pattern) {
return ProjectManager.getAllFiles()
.then(function (files) {
return NGUtils.findMatches(pattern, directiveName, files, true);
});
}
/**
* @private
* For unit and performance tests. Allows lookup by function name instead of editor offset .
*
* @param {!Editor} hostEditor
* @param {!string} directiveName
* @return {$.Promise} a promise that will be resolved with an InlineWidget
* or null if we're not going to provide anything.
*/
function _createInlineEditor(hostEditor, directiveName, pattern) {
// Use Tern jump-to-definition helper, if it's available, to find InlineEditor target.
var helper = brackets._jsCodeHintsHelper;
if (helper === null) {
return null;
}
var result = new $.Deferred();
var response = helper();
if (response.hasOwnProperty("promise")) {
response.promise.done(function (jumpResp) {
var resolvedPath = jumpResp.fullPath;
if (resolvedPath) {
// Tern doesn't always return entire function extent.
// Use QuickEdit search now that we know which file to look at.
var fileInfos = [];
fileInfos.push({name: jumpResp.resultFile, fullPath: resolvedPath});
NGUtils.findMatches(pattern, directiveName, fileInfos, true)
.done(function (functions) {
if (functions && functions.length > 0) {
var jsInlineEditor = new MultiRangeInlineEditor(functions);
jsInlineEditor.load(hostEditor);
result.resolve(jsInlineEditor);
} else {
// No matching functions were found
result.reject();
}
})
.fail(function () {
result.reject();
});
} else { // no result from Tern. Fall back to _findInProject().
_findInProject(directiveName, pattern).done(function (functions) {
if (functions && functions.length > 0) {
var jsInlineEditor = new MultiRangeInlineEditor(functions);
jsInlineEditor.load(hostEditor);
result.resolve(jsInlineEditor);
} else {
// No matching functions were found
result.reject();
}
}).fail(function () {
result.reject();
});
}
}).fail(function () {
result.reject();
});
}
return result.promise();
}
/**
* This function is registered with EditorManager as an inline editor provider. It creates an inline editor
* when the cursor is on a JavaScript function name, finds all functions that match the name
* and shows (one/all of them) in an inline editor.
*
* @param {!Editor} editor
* @param {!{line:Number, ch:Number}} pos
* @return {$.Promise} a promise that will be resolved with an InlineWidget
* or null if we're not going to provide anything.
*/
function provider(hostEditor, pos) {
// Only provide an editor when cursor is in HTML content
if (hostEditor.getModeForSelection() !== "html") {
return null;
}
// Only provide an editor if the selection is within a single line
var sel = hostEditor.getSelection();
if (sel.start.line !== sel.end.line) {
return null;
}
// Always use the selection start for determining the function name. The pos
// parameter is usually the selection end.
var controllerName = _getControllerName(hostEditor, sel.start);
if (controllerName) {
return _createInlineEditor(hostEditor, controllerName, patterns.controller);
}
var directiveName = _getDirectiveName(hostEditor, sel.start);
if (directiveName) {
return _createInlineEditor(hostEditor, directiveName, patterns.directive);
}
return null;
}
// init
EditorManager.registerInlineEditProvider(provider, 10);
});