Skip to content

Commit 08f51e1

Browse files
committed
Web IDE: ajout de tabIndent.
1 parent 084a7f6 commit 08f51e1

File tree

10 files changed

+289
-1
lines changed

10 files changed

+289
-1
lines changed

doc.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,7 @@
13291329
* **jQuery**, par John Resig et la communauté — [site officiel](http://jquery.com/)
13301330
* **jQuery-term**, par Jakub T. Jankiewicz — [site officiel](http://terminal.jcubic.pl/)
13311331
* **parenedit**, — [basé sur cette réponse](http://stackoverflow.com/questions/14043727/auto-resizing-textarea-is-bumpy-highlighting-parentheses)
1332+
* **tabIndent**, par Julian Lam — [site officiel](http://julianlam.github.io/tabIndent.js/)
13321333
* **Blockly**, par Neil Fraser et la communauté — [site officiel](http://code.google.com/p/blockly/)
13331334
* **SciTE**, par Neil Hodgson — [site officiel](http://www.scintilla.org/SciTE.html)
13341335
* **svg-tree-drawer**, par Weston Ruter — [GitHub](https://github.com/westonruter/svg-tree-drawer/)

ide.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,10 @@ <h3>Consoles interactives</h3>
121121
': # Voici la console interactive de MicroAlg.\n' +
122122
': # <- le # indique que la fin de la ligne est un commentaire.');
123123
</script>
124+
<script type="text/javascript" src="web/tabIndent.js"></script>
125+
<script>
126+
tabIndent.config.tab = ' ';
127+
tabIndent.renderAll();
128+
</script>
124129
</body>
125130
</html>

tuto.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,11 @@ <h2 id="fin">Fin</h2>
17281728
<br>
17291729
<br>
17301730
<br>
1731+
<script type="text/javascript" src="web/tabIndent.js"></script>
1732+
<script>
1733+
tabIndent.config.tab = ' ';
1734+
tabIndent.renderAll();
1735+
</script>
17311736
<script>
17321737
$().showUp('.navbar', {
17331738
upClass: 'navbar-show',

tuto_blocs.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,11 @@ <h2 id="suite">La suite</h2>
804804
<br>
805805
<br>
806806
<br>
807+
<script type="text/javascript" src="web/tabIndent.js"></script>
808+
<script>
809+
tabIndent.config.tab = ' ';
810+
tabIndent.renderAll();
811+
</script>
807812
<script>
808813
$().showUp('.navbar', {
809814
upClass: 'navbar-show',

tuto_blocs_2.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,11 @@ <h2 id="fin">Fin</h2>
775775
<br>
776776
<br>
777777
<br>
778+
<script type="text/javascript" src="web/tabIndent.js"></script>
779+
<script>
780+
tabIndent.config.tab = ' ';
781+
tabIndent.renderAll();
782+
</script>
778783
<script>
779784
$().showUp('.navbar', {
780785
upClass: 'navbar-show',

tuto_graphique.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,11 @@ <h2 id="fin">Fin</h2>
450450
<br>
451451
<br>
452452
<br>
453+
<script type="text/javascript" src="web/tabIndent.js"></script>
454+
<script>
455+
tabIndent.config.tab = ' ';
456+
tabIndent.renderAll();
457+
</script>
453458
<script>
454459
$().showUp('.navbar', {
455460
upClass: 'navbar-show',

tuto_rapide.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,11 @@ <h2 id="fin">Fin</h2>
13431343
<br>
13441344
<br>
13451345
<br>
1346+
<script type="text/javascript" src="web/tabIndent.js"></script>
1347+
<script>
1348+
tabIndent.config.tab = ' ';
1349+
tabIndent.renderAll();
1350+
</script>
13461351
<script>
13471352
$().showUp('.navbar', {
13481353
upClass: 'navbar-show',

tuto_simple.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,11 @@ <h2 id="fin">Fin</h2>
17151715
<br>
17161716
<br>
17171717
<br>
1718+
<script type="text/javascript" src="web/tabIndent.js"></script>
1719+
<script>
1720+
tabIndent.config.tab = ' ';
1721+
tabIndent.renderAll();
1722+
</script>
17181723
<script>
17191724
$().showUp('.navbar', {
17201725
upClass: 'navbar-show',

web/ide_injections.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ function inject_microalg_editor_in(elt_id, config) {
312312
'<div id="' + export_id + '"></div>' +
313313
((config.blockly || config.blockly_only) ? '<div id="' + blockly_id + '"></div>' : '') +
314314
'<div ' + hidden + '><textarea id="' + editor_id + '" ' +
315-
'class="malg-editor" cols="80" rows="2"' +
315+
'class="tabIndent malg-editor" cols="80" rows="2"' +
316316
'spellcheck="false">' + src + '</textarea></div>' +
317317
'<select id="' + output_type_id + '" class="malg-output-type">' +
318318
'<option' + ((config.output == 'brut')?' selected':'') + '>brut</option>' +

web/tabIndent.js

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
tabIndent = {
2+
version: '0.1.8',
3+
config: {
4+
tab: '\t'
5+
},
6+
events: {
7+
keydown: function(e) {
8+
var tab = tabIndent.config.tab;
9+
var tabWidth = tab.length;
10+
if (e.keyCode === 9) {
11+
e.preventDefault();
12+
var currentStart = this.selectionStart,
13+
currentEnd = this.selectionEnd;
14+
if (e.shiftKey === false) {
15+
// Normal Tab Behaviour
16+
if (!tabIndent.isMultiLine(this)) {
17+
// Add tab before selection, maintain highlighted text selection
18+
this.value = this.value.slice(0, currentStart) + tab + this.value.slice(currentStart);
19+
this.selectionStart = currentStart + tabWidth;
20+
this.selectionEnd = currentEnd + tabWidth;
21+
} else {
22+
// Iterating through the startIndices, if the index falls within selectionStart and selectionEnd, indent it there.
23+
var startIndices = tabIndent.findStartIndices(this),
24+
l = startIndices.length,
25+
newStart = undefined,
26+
newEnd = undefined,
27+
affectedRows = 0;
28+
29+
while(l--) {
30+
var lowerBound = startIndices[l];
31+
if (startIndices[l+1] && currentStart != startIndices[l+1]) lowerBound = startIndices[l+1];
32+
33+
if (lowerBound >= currentStart && startIndices[l] < currentEnd) {
34+
this.value = this.value.slice(0, startIndices[l]) + tab + this.value.slice(startIndices[l]);
35+
36+
newStart = startIndices[l];
37+
if (!newEnd) newEnd = (startIndices[l+1] ? startIndices[l+1] - 1 : 'end');
38+
affectedRows++;
39+
}
40+
}
41+
42+
this.selectionStart = newStart;
43+
this.selectionEnd = (newEnd !== 'end' ? newEnd + (tabWidth * affectedRows) : this.value.length);
44+
}
45+
} else {
46+
// Shift-Tab Behaviour
47+
if (!tabIndent.isMultiLine(this)) {
48+
if (this.value.substr(currentStart - tabWidth, tabWidth) == tab) {
49+
// If there's a tab before the selectionStart, remove it
50+
this.value = this.value.substr(0, currentStart - tabWidth) + this.value.substr(currentStart);
51+
this.selectionStart = currentStart - tabWidth;
52+
this.selectionEnd = currentEnd - tabWidth;
53+
} else if (this.value.substr(currentStart - 1, 1) == "\n" && this.value.substr(currentStart, tabWidth) == tab) {
54+
// However, if the selection is at the start of the line, and the first character is a tab, remove it
55+
this.value = this.value.substring(0, currentStart) + this.value.substr(currentStart + tabWidth);
56+
this.selectionStart = currentStart;
57+
this.selectionEnd = currentEnd - tabWidth;
58+
}
59+
} else {
60+
// Iterating through the startIndices, if the index falls within selectionStart and selectionEnd, remove an indent from that row
61+
var startIndices = tabIndent.findStartIndices(this),
62+
l = startIndices.length,
63+
newStart = undefined,
64+
newEnd = undefined,
65+
affectedRows = 0;
66+
67+
while(l--) {
68+
var lowerBound = startIndices[l];
69+
if (startIndices[l+1] && currentStart != startIndices[l+1]) lowerBound = startIndices[l+1];
70+
71+
if (lowerBound >= currentStart && startIndices[l] < currentEnd) {
72+
if (this.value.substr(startIndices[l], tabWidth) == tab) {
73+
// Remove a tab
74+
this.value = this.value.slice(0, startIndices[l]) + this.value.slice(startIndices[l] + tabWidth);
75+
affectedRows++;
76+
} else {} // Do nothing
77+
78+
newStart = startIndices[l];
79+
if (!newEnd) newEnd = (startIndices[l+1] ? startIndices[l+1] - 1 : 'end');
80+
}
81+
}
82+
83+
this.selectionStart = newStart;
84+
this.selectionEnd = (newEnd !== 'end' ? newEnd - (affectedRows * tabWidth) : this.value.length);
85+
}
86+
}
87+
} else if (e.keyCode === 27) { // Esc
88+
tabIndent.events.disable(e);
89+
} else if (e.keyCode === 13 && e.shiftKey === false) { // Enter
90+
var self = tabIndent,
91+
cursorPos = this.selectionStart,
92+
startIndices = self.findStartIndices(this),
93+
numStartIndices = startIndices.length,
94+
startIndex = 0,
95+
endIndex = 0,
96+
tabMatch = new RegExp("^" + tab.replace('\t', '\\t').replace(/ /g, '\\s') + "+", 'g'),
97+
lineText = '';
98+
tabs = null;
99+
100+
for(var x=0;x<numStartIndices;x++) {
101+
if (startIndices[x+1] && (cursorPos >= startIndices[x]) && (cursorPos < startIndices[x+1])) {
102+
startIndex = startIndices[x];
103+
endIndex = startIndices[x+1] - 1;
104+
break;
105+
} else {
106+
startIndex = startIndices[numStartIndices-1];
107+
endIndex = this.value.length;
108+
}
109+
}
110+
111+
lineText = this.value.slice(startIndex, endIndex);
112+
tabs = lineText.match(tabMatch);
113+
if (tabs !== null) {
114+
e.preventDefault();
115+
var indentText = tabs[0];
116+
var indentWidth = indentText.length;
117+
var inLinePos = cursorPos - startIndex;
118+
if (indentWidth > inLinePos) {
119+
indentWidth = inLinePos;
120+
indentText = indentText.slice(0, inLinePos);
121+
}
122+
123+
this.value = this.value.slice(0, cursorPos) + "\n" + indentText + this.value.slice(cursorPos);
124+
this.selectionStart = cursorPos + indentWidth + 1;
125+
this.selectionEnd = this.selectionStart;
126+
}
127+
}
128+
},
129+
disable: function(e) {
130+
var events = this;
131+
132+
// Temporarily suspend the main tabIndent event
133+
tabIndent.remove(e.target);
134+
},
135+
focus: function() {
136+
var self = tabIndent,
137+
el = this,
138+
delayedRefocus = setTimeout(function() {
139+
var classes = (el.getAttribute('class') || '').split(' '),
140+
contains = classes.indexOf('tabIndent');
141+
142+
el.addEventListener('keydown', self.events.keydown);
143+
el.style.backgroundImage = "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAAEgAAABIAEbJaz4AAAKZSURBVEjH7ZRfSFNRHMe/9+/+3G26tUn+ycywgURgUBAUJlIhWlEQEjN8yQcfolKJxJAefOjRCnT0IPYQ9iRa9FAYJiaUVP4twf7gzJzpnDbdzHt3z+3Fua3dO4Ne/f5ezjmc8+F7zvmeA2zrv0VFGlexAssFw1mG1pqqUL8npGY60Bw3ykYaOVjlrFXmEyw0AQj6g53UONQBO8DBzuiT2tUx+gR/mwACBQpIUoACBZoAZaOSiWwFIFs4oMMS9/boZVF8T8vtkbEofatiRKF9mXK6M7tTyyxRaPwWtJezIu9+9cNzxHk/n9938rz6IWpvgRdZd5/HcsvC9jadqk6Z0qkBiCaAF3UtX8cy6h1mwlnLhsuZuRvqABlyNJqb0q0ZWsb7uUVHlXAahWl1y3M2tVuQVR1Q0Pl0dwZ67KbZtGnX/ma++/FsCCY1ANlAxIuT2NZP3XB/GRKc9qKhKTYnd4auJbIqINEBDa5zoWWByoS1jocR+loKpKGJKqBLybN/OQN2Tmodv4jCtYIMYurnP5sLf+V5XK4DbFv4haaDCEABA/J88GdegD1I2+heY0Xj7M1itiMjP8srzutjXMbkIDZKCrAcfGOt8LwODimYnzzjLcHIx5VFwPekZrhVPYmxyVNAvZP8KV28SykClo6XF4/t9LpC2TTIteulJepJjD5nCjL8E56sMHt40NYYqE51ZnZIfmGXYBC68p/6v6UkApSI8Y2ejPVKhyE0PdLDPcg+Z003G0W7YUmmvo/WtjXgbiKAAQNGpjYRDOwWILx3dV16ZBsx3QsdYi4JNUw6uCvMbrUcWFAvPWznfH9/GQHR5xAbPuTumRFWvS+ZwDGyJFfidkxWk2oaIfTRk8RI0YqMAQBAL7YVrz/iUDx4QII4/QAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0xMi0wMVQwMDowNjo0My0wNTowMLKpTWYAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMTItMDFUMDA6MDY6NDMtMDU6MDDD9PXaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==)";
144+
el.style.backgroundPosition = 'top right';
145+
el.style.backgroundRepeat = 'no-repeat';
146+
147+
if (contains !== -1) classes.splice(contains, 1);
148+
classes.push('tabIndent-rendered');
149+
el.setAttribute('class', classes.join(' '));
150+
151+
el.removeEventListener('focus', self.events.keydown);
152+
}, 500);
153+
154+
// If they were just tabbing through the input, let them continue unimpeded
155+
el.addEventListener('blur', function b() {
156+
clearTimeout(delayedRefocus);
157+
el.removeEventListener('blur', b);
158+
});
159+
}
160+
},
161+
render: function(el) {
162+
var self = this;
163+
164+
if (el.nodeName === 'TEXTAREA') {
165+
el.addEventListener('focus', self.events.focus);
166+
167+
el.addEventListener('blur', function b(e) {
168+
self.events.disable(e);
169+
});
170+
}
171+
},
172+
renderAll: function() {
173+
// Find all elements with the tabIndent class
174+
var textareas = document.getElementsByTagName('textarea'),
175+
t = textareas.length,
176+
contains = -1,
177+
classes = [],
178+
el = undefined;
179+
180+
while(t--) {
181+
classes = (textareas[t].getAttribute('class') || '').split(' ');
182+
contains = classes.indexOf('tabIndent');
183+
184+
if (contains !== -1) {
185+
el = textareas[t];
186+
this.render(el);
187+
}
188+
contains = -1;
189+
classes = [];
190+
el = undefined;
191+
}
192+
},
193+
remove: function(el) {
194+
if (el.nodeName === 'TEXTAREA') {
195+
var classes = (el.getAttribute('class') || '').split(' '),
196+
contains = classes.indexOf('tabIndent-rendered');
197+
198+
if (contains !== -1) {
199+
el.removeEventListener('keydown', this.events.keydown);
200+
el.style.backgroundImage = '';
201+
202+
classes.splice(contains, 1);
203+
classes.push('tabIndent');
204+
el.setAttribute('class', (classes.length > 1 ? classes.join(' ') : classes[0]));
205+
}
206+
}
207+
},
208+
removeAll: function() {
209+
// Find all elements with the tabIndent class
210+
var textareas = document.getElementsByTagName('textarea'),
211+
t = textareas.length,
212+
contains = -1,
213+
classes = [],
214+
el = undefined;
215+
216+
while(t--) {
217+
classes = (textareas[t].getAttribute('class') || '').split(' ');
218+
contains = classes.indexOf('tabIndent-rendered');
219+
220+
if (contains !== -1) {
221+
el = textareas[t];
222+
this.remove(el);
223+
}
224+
contains = -1;
225+
classes = [];
226+
el = undefined;
227+
}
228+
},
229+
isMultiLine: function(el) {
230+
// Extract the selection
231+
var snippet = el.value.slice(el.selectionStart, el.selectionEnd),
232+
nlRegex = new RegExp(/\n/);
233+
234+
if (nlRegex.test(snippet)) return true;
235+
else return false;
236+
},
237+
findStartIndices: function(el) {
238+
var text = el.value,
239+
startIndices = [],
240+
offset = 0;
241+
242+
while(text.match(/\n/) && text.match(/\n/).length > 0) {
243+
offset = (startIndices.length > 0 ? startIndices[startIndices.length - 1] : 0);
244+
var lineEnd = text.search("\n");
245+
startIndices.push(lineEnd + offset + 1);
246+
text = text.substring(lineEnd + 1);
247+
}
248+
startIndices.unshift(0);
249+
250+
return startIndices;
251+
}
252+
}

0 commit comments

Comments
 (0)