resin 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/README.markdown +52 -0
  2. data/amber/css/amber.css +519 -0
  3. data/amber/css/documentation.css +84 -0
  4. data/amber/css/profstef.css +75 -0
  5. data/amber/css/style.css +313 -0
  6. data/amber/images/amber.png +0 -0
  7. data/amber/images/amber_small.png +0 -0
  8. data/amber/images/off.png +0 -0
  9. data/amber/images/offHover.png +0 -0
  10. data/amber/images/presentation.png +0 -0
  11. data/amber/images/profstef.png +0 -0
  12. data/amber/images/sprite.png +0 -0
  13. data/amber/images/tinylogo.png +0 -0
  14. data/amber/images/twitterwall.png +0 -0
  15. data/amber/js/Additional-Examples.deploy.js +15 -0
  16. data/amber/js/Additional-Examples.js +21 -0
  17. data/amber/js/Benchfib.deploy.js +132 -0
  18. data/amber/js/Benchfib.js +167 -0
  19. data/amber/js/Canvas.deploy.js +1304 -0
  20. data/amber/js/Canvas.js +1885 -0
  21. data/amber/js/Compiler.deploy.js +1871 -0
  22. data/amber/js/Compiler.js +2616 -0
  23. data/amber/js/Documentation.deploy.js +961 -0
  24. data/amber/js/Documentation.js +1376 -0
  25. data/amber/js/Examples.deploy.js +53 -0
  26. data/amber/js/Examples.js +73 -0
  27. data/amber/js/IDE.deploy.js +3468 -0
  28. data/amber/js/IDE.js +4883 -0
  29. data/amber/js/Kernel-Announcements.deploy.js +107 -0
  30. data/amber/js/Kernel-Announcements.js +152 -0
  31. data/amber/js/Kernel-Classes.deploy.js +675 -0
  32. data/amber/js/Kernel-Classes.js +956 -0
  33. data/amber/js/Kernel-Collections.deploy.js +3273 -0
  34. data/amber/js/Kernel-Collections.js +4644 -0
  35. data/amber/js/Kernel-Exceptions.deploy.js +244 -0
  36. data/amber/js/Kernel-Exceptions.js +349 -0
  37. data/amber/js/Kernel-Methods.deploy.js +510 -0
  38. data/amber/js/Kernel-Methods.js +739 -0
  39. data/amber/js/Kernel-Objects.deploy.js +2698 -0
  40. data/amber/js/Kernel-Objects.js +3858 -0
  41. data/amber/js/Kernel-Tests.deploy.js +1419 -0
  42. data/amber/js/Kernel-Tests.js +1929 -0
  43. data/amber/js/Kernel-Transcript.deploy.js +142 -0
  44. data/amber/js/Kernel-Transcript.js +202 -0
  45. data/amber/js/SUnit.deploy.js +351 -0
  46. data/amber/js/SUnit.js +501 -0
  47. data/amber/js/amber.js +250 -0
  48. data/amber/js/boot.js +587 -0
  49. data/amber/js/compat.js +22 -0
  50. data/amber/js/init.js +8 -0
  51. data/amber/js/lib/CodeMirror/LICENSE +19 -0
  52. data/amber/js/lib/CodeMirror/amber.css +21 -0
  53. data/amber/js/lib/CodeMirror/codemirror.css +67 -0
  54. data/amber/js/lib/CodeMirror/codemirror.js +2144 -0
  55. data/amber/js/lib/CodeMirror/smalltalk.js +134 -0
  56. data/amber/js/lib/jQuery/jquery-1.4.4.min.js +167 -0
  57. data/amber/js/lib/jQuery/jquery-1.6.4.min.js +4 -0
  58. data/amber/js/lib/jQuery/jquery-ui-1.8.16.custom.min.js +791 -0
  59. data/amber/js/lib/jQuery/jquery.textarea.js +267 -0
  60. data/amber/js/lib/peg-0.6.2.min.js +2 -0
  61. data/amber/js/lib/showdown.js +419 -0
  62. data/amber/js/parser.js +4005 -0
  63. data/amber/js/parser.pegjs +220 -0
  64. data/amber/st/Benchfib.st +124 -0
  65. data/amber/st/Canvas.st +556 -0
  66. data/amber/st/Compiler.st +1425 -0
  67. data/amber/st/Documentation.st +758 -0
  68. data/amber/st/Examples.st +38 -0
  69. data/amber/st/IDE.st +2336 -0
  70. data/amber/st/Kernel-Announcements.st +61 -0
  71. data/amber/st/Kernel-Classes.st +403 -0
  72. data/amber/st/Kernel-Collections.st +1673 -0
  73. data/amber/st/Kernel-Exceptions.st +124 -0
  74. data/amber/st/Kernel-Methods.st +287 -0
  75. data/amber/st/Kernel-Objects.st +1489 -0
  76. data/amber/st/Kernel-Tests.st +892 -0
  77. data/amber/st/Kernel-Transcript.st +70 -0
  78. data/amber/st/SUnit.st +172 -0
  79. data/bin/runresin +12 -0
  80. data/lib/resin.rb +0 -0
  81. data/lib/resin/app/app.rb +121 -0
  82. data/lib/resin/app/views/index.haml +10 -0
  83. metadata +216 -0
@@ -0,0 +1,38 @@
1
+ Smalltalk current createPackage: 'Examples' properties: #{}!
2
+ Widget subclass: #Counter
3
+ instanceVariableNames: 'count header'
4
+ category: 'Examples'!
5
+
6
+ !Counter methodsFor: 'actions'!
7
+
8
+ increase
9
+ count := count + 1.
10
+ header contents: [:html | html with: count asString]
11
+ !
12
+
13
+ decrease
14
+ count := count - 1.
15
+ header contents: [:html | html with: count asString]
16
+ ! !
17
+
18
+ !Counter methodsFor: 'initialization'!
19
+
20
+ initialize
21
+ super initialize.
22
+ count := 0
23
+ ! !
24
+
25
+ !Counter methodsFor: 'rendering'!
26
+
27
+ renderOn: html
28
+ header := html h1
29
+ with: count asString;
30
+ yourself.
31
+ html button
32
+ with: '++';
33
+ onClick: [self increase].
34
+ html button
35
+ with: '--';
36
+ onClick: [self decrease]
37
+ ! !
38
+
@@ -0,0 +1,2336 @@
1
+ Smalltalk current createPackage: 'IDE' properties: #{}!
2
+ Widget subclass: #TabManager
3
+ instanceVariableNames: 'selectedTab tabs opened ul input'
4
+ category: 'IDE'!
5
+
6
+ !TabManager methodsFor: 'accessing'!
7
+
8
+ tabs
9
+ ^tabs ifNil: [tabs := Array new]
10
+ !
11
+
12
+ labelFor: aWidget
13
+ | label maxSize |
14
+ maxSize := 15.
15
+ label := aWidget label copyFrom: 0 to: (aWidget label size min: maxSize).
16
+ aWidget label size > maxSize ifTrue: [
17
+ label := label, '...'].
18
+ ^label
19
+ ! !
20
+
21
+ !TabManager methodsFor: 'actions'!
22
+
23
+ updateBodyMargin
24
+ self setBodyMargin: '#jtalk' asJQuery height
25
+ !
26
+
27
+ updatePosition
28
+ <jQuery('#jtalk').css('top', '').css('bottom', '0px')>
29
+ !
30
+
31
+ removeBodyMargin
32
+ self setBodyMargin: 0
33
+ !
34
+
35
+ setBodyMargin: anInteger
36
+ '.jtalkBody' asJQuery css: 'margin-bottom' put: anInteger asString, 'px'
37
+ !
38
+
39
+ onResize: aBlock
40
+ <jQuery('#jtalk').resizable({
41
+ handles: 'n',
42
+ resize: aBlock,
43
+ minHeight: 230
44
+ })>
45
+ !
46
+
47
+ onWindowResize: aBlock
48
+ <jQuery(window).resize(aBlock)>
49
+ !
50
+
51
+ open
52
+ opened ifFalse: [
53
+ 'body' asJQuery addClass: 'jtalkBody'.
54
+ '#jtalk' asJQuery show.
55
+ ul asJQuery show.
56
+ self updateBodyMargin.
57
+ selectedTab show.
58
+ opened := true]
59
+ !
60
+
61
+ close
62
+ opened ifTrue: [
63
+ '#jtalk' asJQuery hide.
64
+ ul asJQuery hide.
65
+ selectedTab hide.
66
+ self removeBodyMargin.
67
+ 'body' asJQuery removeClass: 'jtalkBody'.
68
+ opened := false]
69
+ !
70
+
71
+ newBrowserTab
72
+ Browser open
73
+ !
74
+
75
+ selectTab: aWidget
76
+ self open.
77
+ selectedTab := aWidget.
78
+ self tabs do: [:each |
79
+ each hide].
80
+ aWidget show.
81
+
82
+ self update
83
+ !
84
+
85
+ closeTab: aWidget
86
+ self removeTab: aWidget.
87
+ self selectTab: self tabs last.
88
+ aWidget remove.
89
+ self update
90
+ !
91
+
92
+ search: aString
93
+ | searchedClass |
94
+ searchedClass := Smalltalk current at: aString.
95
+ searchedClass isClass
96
+ ifTrue: [Browser openOn: searchedClass]
97
+ ifFalse: [ReferencesBrowser search: aString]
98
+ ! !
99
+
100
+ !TabManager methodsFor: 'adding/Removing'!
101
+
102
+ addTab: aWidget
103
+ self tabs add: aWidget.
104
+ aWidget appendToJQuery: '#jtalk' asJQuery.
105
+ aWidget hide
106
+ !
107
+
108
+ removeTab: aWidget
109
+ self tabs remove: aWidget.
110
+ self update
111
+ ! !
112
+
113
+ !TabManager methodsFor: 'initialization'!
114
+
115
+ initialize
116
+ super initialize.
117
+ opened := true.
118
+ [:html | html div id: 'jtalk'] appendToJQuery: 'body' asJQuery.
119
+ 'body' asJQuery
120
+ addClass: 'jtalkBody'.
121
+ self appendToJQuery: '#jtalk' asJQuery.
122
+ self
123
+ addTab: IDETranscript current;
124
+ addTab: Workspace new;
125
+ addTab: TestRunner new.
126
+ self selectTab: self tabs last.
127
+ self
128
+ onResize: [self updateBodyMargin; updatePosition];
129
+ onWindowResize: [self updatePosition]
130
+ ! !
131
+
132
+ !TabManager methodsFor: 'rendering'!
133
+
134
+ renderOn: html
135
+ html div id: 'logo'.
136
+ self renderToolbarOn: html.
137
+ ul := html ul
138
+ id: 'jtalkTabs';
139
+ yourself.
140
+ self renderTabs
141
+ !
142
+
143
+ renderTabFor: aWidget on: html
144
+ | li |
145
+ li := html li.
146
+ selectedTab = aWidget ifTrue: [
147
+ li class: 'selected'].
148
+ li with: [
149
+ html span class: 'ltab'.
150
+ html span
151
+ class: 'mtab';
152
+ with: [
153
+ aWidget canBeClosed ifTrue: [
154
+ html span
155
+ class: 'close';
156
+ with: 'x';
157
+ onClick: [self closeTab: aWidget]].
158
+ html span with: (self labelFor: aWidget)].
159
+ html span class: 'rtab'];
160
+ onClick: [self selectTab: aWidget]
161
+ !
162
+
163
+ renderTabs
164
+ ul contents: [:html |
165
+ self tabs do: [:each |
166
+ self renderTabFor: each on: html].
167
+ html li
168
+ class: 'newtab';
169
+ with: [
170
+ html span class: 'ltab'.
171
+ html span class: 'mtab'; with: ' + '.
172
+ html span class: 'rtab'];
173
+ onClick: [self newBrowserTab]]
174
+ !
175
+
176
+ renderToolbarOn: html
177
+ html div
178
+ id: 'jt_toolbar';
179
+ with: [
180
+ input := html input
181
+ class: 'implementors';
182
+ yourself.
183
+ input onKeyPress: [:event |
184
+ event keyCode = 13 ifTrue: [
185
+ self search: input asJQuery val]].
186
+ html div id: 'jt_close'; onClick: [self close]]
187
+ ! !
188
+
189
+ !TabManager methodsFor: 'updating'!
190
+
191
+ update
192
+ self renderTabs
193
+ ! !
194
+
195
+ TabManager class instanceVariableNames: 'current'!
196
+
197
+ !TabManager class methodsFor: 'instance creation'!
198
+
199
+ current
200
+ ^current ifNil: [current := super new]
201
+ !
202
+
203
+ new
204
+ self shouldNotImplement
205
+ ! !
206
+
207
+ Widget subclass: #TabWidget
208
+ instanceVariableNames: 'div'
209
+ category: 'IDE'!
210
+
211
+ !TabWidget methodsFor: 'accessing'!
212
+
213
+ label
214
+ self subclassResponsibility
215
+ ! !
216
+
217
+ !TabWidget methodsFor: 'actions'!
218
+
219
+ open
220
+ TabManager current addTab: self.
221
+ TabManager current selectTab: self
222
+ !
223
+
224
+ show
225
+ div asJQuery show
226
+ !
227
+
228
+ hide
229
+ div asJQuery hide
230
+ !
231
+
232
+ remove
233
+ div asJQuery remove
234
+ !
235
+
236
+ close
237
+ TabManager current closeTab: self
238
+ ! !
239
+
240
+ !TabWidget methodsFor: 'rendering'!
241
+
242
+ renderOn: html
243
+ div := html div
244
+ class: 'jtalkTool';
245
+ yourself.
246
+ self renderTab
247
+ !
248
+
249
+ renderBoxOn: html
250
+ !
251
+
252
+ renderButtonsOn: html
253
+ !
254
+
255
+ update
256
+ self renderTab
257
+ !
258
+
259
+ renderTab
260
+ div contents: [:html |
261
+ html div
262
+ class: 'jt_box';
263
+ with: [self renderBoxOn: html].
264
+ html div
265
+ class: 'jt_buttons';
266
+ with: [self renderButtonsOn: html]]
267
+ ! !
268
+
269
+ !TabWidget methodsFor: 'testing'!
270
+
271
+ canBeClosed
272
+ ^false
273
+ ! !
274
+
275
+ !TabWidget class methodsFor: 'instance creation'!
276
+
277
+ open
278
+ ^self new open
279
+ ! !
280
+
281
+ TabWidget subclass: #Workspace
282
+ instanceVariableNames: 'sourceArea'
283
+ category: 'IDE'!
284
+
285
+ !Workspace methodsFor: 'accessing'!
286
+
287
+ label
288
+ ^'Workspace'
289
+ ! !
290
+
291
+ !Workspace methodsFor: 'actions'!
292
+
293
+ clearWorkspace
294
+ sourceArea clear
295
+ !
296
+
297
+ doIt
298
+ sourceArea doIt
299
+ !
300
+
301
+ printIt
302
+ sourceArea printIt
303
+ !
304
+
305
+ inspectIt
306
+ sourceArea inspectIt
307
+ !
308
+
309
+ fileIn
310
+ sourceArea fileIn
311
+ ! !
312
+
313
+ !Workspace methodsFor: 'rendering'!
314
+
315
+ renderBoxOn: html
316
+ sourceArea := SourceArea new.
317
+ sourceArea renderOn: html
318
+ !
319
+
320
+ renderButtonsOn: html
321
+ html button
322
+ with: 'DoIt';
323
+ title: 'ctrl+d';
324
+ onClick: [self doIt].
325
+ html button
326
+ with: 'PrintIt';
327
+ title: 'ctrl+p';
328
+ onClick: [self printIt].
329
+ html button
330
+ with: 'InspectIt';
331
+ title: 'ctrl+i';
332
+ onClick: [self inspectIt].
333
+ html button
334
+ with: 'FileIn';
335
+ title: 'ctrl+f';
336
+ onClick: [self fileIn].
337
+ html button
338
+ with: 'Clear workspace';
339
+ onClick: [self clearWorkspace]
340
+ ! !
341
+
342
+ TabWidget subclass: #Browser
343
+ instanceVariableNames: 'selectedPackage selectedClass selectedProtocol selectedMethod packagesList classesList protocolsList methodsList sourceArea tabsList selectedTab saveButton classButtons methodButtons unsavedChanges'
344
+ category: 'IDE'!
345
+
346
+ !Browser methodsFor: 'accessing'!
347
+
348
+ label
349
+ ^selectedClass
350
+ ifNil: ['Browser (nil)']
351
+ ifNotNil: ['Browser: ', selectedClass name]
352
+ !
353
+
354
+ packages
355
+ | packages |
356
+ packages := Array new.
357
+ Smalltalk current classes do: [:each |
358
+ (packages includes: each category) ifFalse: [
359
+ packages add: each category]].
360
+ ^packages sort
361
+ !
362
+
363
+ classes
364
+ ^(Smalltalk current classes
365
+ select: [:each | each category = selectedPackage])
366
+ sort: [:a :b | a name < b name]
367
+ !
368
+
369
+ protocols
370
+ | klass |
371
+ selectedClass ifNotNil: [
372
+ selectedTab = #comment ifTrue: [^#()].
373
+ klass := selectedTab = #instance
374
+ ifTrue: [selectedClass]
375
+ ifFalse: [selectedClass class].
376
+ klass methodDictionary isEmpty ifTrue: [
377
+ ^Array with: 'not yet classified'].
378
+ ^klass protocols].
379
+ ^Array new
380
+ !
381
+
382
+ methods
383
+ | klass |
384
+ selectedTab = #comment ifTrue: [^#()].
385
+ selectedClass ifNotNil: [
386
+ klass := selectedTab = #instance
387
+ ifTrue: [selectedClass]
388
+ ifFalse: [selectedClass class]].
389
+ ^(selectedProtocol
390
+ ifNil: [
391
+ klass
392
+ ifNil: [#()]
393
+ ifNotNil: [klass methodDictionary values]]
394
+ ifNotNil: [
395
+ klass methodDictionary values select: [:each |
396
+ each category = selectedProtocol]]) sort: [:a :b | a selector < b selector]
397
+ !
398
+
399
+ source
400
+ selectedTab = #comment ifFalse: [
401
+ ^(selectedProtocol notNil or: [selectedMethod notNil])
402
+ ifFalse: [self declarationSource]
403
+ ifTrue: [self methodSource]].
404
+ ^selectedClass
405
+ ifNil: ['']
406
+ ifNotNil: [self classCommentSource]
407
+ !
408
+
409
+ methodSource
410
+ ^selectedMethod
411
+ ifNil: [self dummyMethodSource]
412
+ ifNotNil: [selectedMethod source]
413
+ !
414
+
415
+ dummyMethodSource
416
+ ^'messageSelectorAndArgumentNames
417
+ "comment stating purpose of message"
418
+
419
+ | temporary variable names |
420
+ statements'
421
+ !
422
+
423
+ declarationSource
424
+ ^selectedTab = #instance
425
+ ifTrue: [self classDeclarationSource]
426
+ ifFalse: [self metaclassDeclarationSource]
427
+ !
428
+
429
+ classDeclarationSource
430
+ | stream |
431
+ stream := '' writeStream.
432
+ selectedClass ifNil: [^self classDeclarationTemplate].
433
+ stream
434
+ nextPutAll: selectedClass superclass asString;
435
+ nextPutAll: ' subclass: #';
436
+ nextPutAll: selectedClass name;
437
+ nextPutAll: String lf, String tab;
438
+ nextPutAll: 'instanceVariableNames: '''.
439
+ selectedClass instanceVariableNames
440
+ do: [:each | stream nextPutAll: each]
441
+ separatedBy: [stream nextPutAll: ' '].
442
+ stream
443
+ nextPutAll: '''', String lf, String tab;
444
+ nextPutAll: 'package: ''';
445
+ nextPutAll: selectedClass category;
446
+ nextPutAll: ''''.
447
+ ^stream contents
448
+ !
449
+
450
+ metaclassDeclarationSource
451
+ | stream |
452
+ stream := '' writeStream.
453
+ selectedClass ifNotNil: [
454
+ stream
455
+ nextPutAll: selectedClass asString;
456
+ nextPutAll: ' class ';
457
+ nextPutAll: 'instanceVariableNames: '''.
458
+ selectedClass class instanceVariableNames
459
+ do: [:each | stream nextPutAll: each]
460
+ separatedBy: [stream nextPutAll: ' '].
461
+ stream nextPutAll: ''''].
462
+ ^stream contents
463
+ !
464
+
465
+ classCommentSource
466
+ ^selectedClass comment
467
+ !
468
+
469
+ selectedClass
470
+ ^selectedClass
471
+ !
472
+
473
+ classDeclarationTemplate
474
+ ^'Object subclass: #NameOfSubclass
475
+ instanceVariableNames: ''''
476
+ package: ''', self selectedPackage, ''''
477
+ !
478
+
479
+ selectedPackage
480
+ ^selectedPackage
481
+ ! !
482
+
483
+ !Browser methodsFor: 'actions'!
484
+
485
+ disableSaveButton
486
+ saveButton ifNotNil: [
487
+ saveButton at: 'disabled' put: true].
488
+ unsavedChanges := false
489
+ !
490
+
491
+ hideClassButtons
492
+ classButtons asJQuery hide
493
+ !
494
+
495
+ showClassButtons
496
+ classButtons asJQuery show
497
+ !
498
+
499
+ hideMethodButtons
500
+ methodButtons asJQuery hide
501
+ !
502
+
503
+ showMethodButtons
504
+ methodButtons asJQuery show
505
+ !
506
+
507
+ compile
508
+ self disableSaveButton.
509
+ selectedTab = #comment
510
+ ifTrue: [
511
+ selectedClass ifNotNil: [
512
+ self compileClassComment]]
513
+ ifFalse: [
514
+ (selectedProtocol notNil or: [selectedMethod notNil])
515
+ ifFalse: [self compileDefinition]
516
+ ifTrue: [self compileMethodDefinition]]
517
+ !
518
+
519
+ compileClassComment
520
+ selectedClass comment: sourceArea val
521
+ !
522
+
523
+ compileMethodDefinition
524
+ selectedTab = #instance
525
+ ifTrue: [self compileMethodDefinitionFor: selectedClass]
526
+ ifFalse: [self compileMethodDefinitionFor: selectedClass class]
527
+ !
528
+
529
+ compileMethodDefinitionFor: aClass
530
+ | compiler method source node |
531
+ source := sourceArea val.
532
+ selectedProtocol ifNil: [selectedProtocol := selectedMethod category].
533
+ compiler := Compiler new.
534
+ compiler source: source.
535
+ node := compiler parse: source.
536
+ node isParseFailure ifTrue: [
537
+ ^window alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].
538
+ compiler currentClass: aClass.
539
+ method := compiler eval: (compiler compileNode: node).
540
+ method category: selectedProtocol.
541
+ compiler unknownVariables do: [:each |
542
+ "Do not try to redeclare javascript's objects"
543
+ (window at: each) ifNil: [
544
+ (window confirm: 'Declare ''', each, ''' as instance variable?') ifTrue: [
545
+ self addInstanceVariableNamed: each toClass: aClass.
546
+ ^self compileMethodDefinitionFor: aClass]]].
547
+ aClass addCompiledMethod: method.
548
+ compiler setupClass: aClass.
549
+ self updateMethodsList.
550
+ self selectMethod: method
551
+ !
552
+
553
+ compileDefinition
554
+ | newClass |
555
+ newClass := Compiler new loadExpression: sourceArea val.
556
+ self
557
+ resetClassesList;
558
+ updateCategoriesList;
559
+ updateClassesList.
560
+ self selectClass: newClass
561
+ !
562
+
563
+ cancelChanges
564
+ ^unsavedChanges
565
+ ifTrue: [window confirm: 'Cancel changes?']
566
+ ifFalse: [true]
567
+ !
568
+
569
+ removeClass
570
+ (window confirm: 'Do you really want to remove ', selectedClass name, '?')
571
+ ifTrue: [
572
+ Smalltalk current removeClass: selectedClass.
573
+ self resetClassesList.
574
+ self selectClass: nil]
575
+ !
576
+
577
+ removeMethod
578
+ self cancelChanges ifTrue: [
579
+ (window confirm: 'Do you really want to remove #', selectedMethod selector, '?')
580
+ ifTrue: [
581
+ selectedTab = #instance
582
+ ifTrue: [selectedClass removeCompiledMethod: selectedMethod]
583
+ ifFalse: [selectedClass class removeCompiledMethod: selectedMethod].
584
+ self selectMethod: nil]]
585
+ !
586
+
587
+ setMethodProtocol: aString
588
+ self cancelChanges ifTrue: [
589
+ (self protocols includes: aString)
590
+ ifFalse: [self addNewProtocol]
591
+ ifTrue: [
592
+ selectedMethod category: aString.
593
+ selectedProtocol := aString.
594
+ selectedMethod := selectedMethod.
595
+ self
596
+ updateProtocolsList;
597
+ updateMethodsList;
598
+ updateSourceAndButtons]]
599
+ !
600
+
601
+ addNewProtocol
602
+ | newProtocol |
603
+ newProtocol := window prompt: 'New method protocol'.
604
+ (newProtocol notNil and: [newProtocol notEmpty]) ifTrue: [
605
+ selectedMethod category: newProtocol.
606
+ self setMethodProtocol: newProtocol]
607
+ !
608
+
609
+ selectCategory: aCategory
610
+ self cancelChanges ifTrue: [
611
+ selectedPackage := aCategory.
612
+ selectedClass := selectedProtocol := selectedMethod := nil.
613
+ self resetClassesList.
614
+ self
615
+ updateCategoriesList;
616
+ updateClassesList;
617
+ updateProtocolsList;
618
+ updateMethodsList;
619
+ updateSourceAndButtons]
620
+ !
621
+
622
+ selectClass: aClass
623
+ self cancelChanges ifTrue: [
624
+ selectedClass := aClass.
625
+ selectedProtocol := selectedMethod := nil.
626
+ self
627
+ updateClassesList;
628
+ updateProtocolsList;
629
+ updateMethodsList;
630
+ updateSourceAndButtons]
631
+ !
632
+
633
+ selectProtocol: aString
634
+ self cancelChanges ifTrue: [
635
+ selectedProtocol := aString.
636
+ selectedMethod := nil.
637
+ self
638
+ updateProtocolsList;
639
+ updateMethodsList;
640
+ updateSourceAndButtons]
641
+ !
642
+
643
+ selectMethod: aMethod
644
+ self cancelChanges ifTrue: [
645
+ selectedMethod := aMethod.
646
+ self
647
+ updateProtocolsList;
648
+ updateMethodsList;
649
+ updateSourceAndButtons]
650
+ !
651
+
652
+ selectTab: aString
653
+ self cancelChanges ifTrue: [
654
+ selectedTab := aString.
655
+ self selectProtocol: nil.
656
+ self updateTabsList]
657
+ !
658
+
659
+ renameClass
660
+ | newName |
661
+ newName := window prompt: 'Rename class ', selectedClass name.
662
+ (newName notNil and: [newName notEmpty]) ifTrue: [
663
+ selectedClass rename: newName.
664
+ self
665
+ updateClassesList;
666
+ updateSourceAndButtons]
667
+ !
668
+
669
+ addInstanceVariableNamed: aString toClass: aClass
670
+ ClassBuilder new
671
+ addSubclassOf: aClass superclass
672
+ named: aClass name
673
+ instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
674
+ package: aClass package name
675
+ !
676
+
677
+ searchReferencesOf: aString
678
+ ReferencesBrowser search: aString
679
+ !
680
+
681
+ searchClassReferences
682
+ ReferencesBrowser search: selectedClass name
683
+ !
684
+
685
+ search: aString
686
+ self cancelChanges ifTrue: [| searchedClass |
687
+ searchedClass := Smalltalk current at: aString.
688
+ searchedClass isClass
689
+ ifTrue: [self class openOn: searchedClass]
690
+ ifFalse: [self searchReferencesOf: aString]]
691
+ !
692
+
693
+ handleSourceAreaKeyDown: anEvent
694
+ <if(anEvent.ctrlKey) {
695
+ if(anEvent.keyCode === 83) { //ctrl+s
696
+ self._compile();
697
+ anEvent.preventDefault();
698
+ return false;
699
+ }
700
+ }
701
+ >
702
+ !
703
+
704
+ commitPackage
705
+ selectedPackage ifNotNil: [ |package|
706
+ package := Package named: selectedPackage.
707
+ { Exporter -> (package commitPathJs, '/', selectedPackage, '.js').
708
+ StrippedExporter -> (package commitPathJs, '/', selectedPackage, '.deploy.js').
709
+ ChunkExporter -> (package commitPathSt, '/', selectedPackage, '.st') }
710
+
711
+ do: [:commitStrategy| |fileContents|
712
+ fileContents := (commitStrategy key new exportPackage: selectedPackage).
713
+ self ajaxPutAt: commitStrategy value data: fileContents]
714
+ ]
715
+ !
716
+
717
+ renamePackage
718
+
719
+ | newName |
720
+ newName := window prompt: 'Rename package ', selectedPackage.
721
+ newName ifNotNil: [
722
+ newName notEmpty ifTrue: [
723
+ Smalltalk current renamePackage: selectedPackage to: newName.
724
+ self updateCategoriesList]]
725
+ !
726
+
727
+ removePackage
728
+
729
+ (window confirm: 'Do you really want to remove the whole package ', selectedPackage, ' with all its classes?')
730
+ ifTrue: [
731
+ Smalltalk current removePackage: selectedPackage.
732
+ self updateCategoriesList]
733
+ !
734
+
735
+ addNewClass
736
+ | className |
737
+ className := window prompt: 'New class'.
738
+ (className notNil and: [className notEmpty]) ifTrue: [
739
+ Object subclass: className instanceVariableNames: '' package: self selectedPackage.
740
+ self
741
+ resetClassesList;
742
+ updateClassesList.
743
+ self selectClass: (Smalltalk current at: className)]
744
+ !
745
+
746
+ copyClass
747
+ | className |
748
+ className := window prompt: 'Copy class'.
749
+ (className notNil and: [className notEmpty]) ifTrue: [
750
+ ClassBuilder new copyClass: self selectedClass named: className.
751
+ self
752
+ resetClassesList;
753
+ updateClassesList.
754
+ self selectClass: (Smalltalk current at: className)]
755
+ ! !
756
+
757
+ !Browser methodsFor: 'initialization'!
758
+
759
+ initialize
760
+ super initialize.
761
+ selectedTab := #instance.
762
+ selectedPackage := self packages first.
763
+ unsavedChanges := false
764
+ ! !
765
+
766
+ !Browser methodsFor: 'network'!
767
+
768
+ ajaxPutAt: anURL data: aString
769
+ jQuery
770
+ ajax: anURL options: #{ 'type' -> 'PUT'.
771
+ 'contentType' -> 'application/json'.
772
+ 'data' -> aString.
773
+ 'error' -> [window alert: 'PUT request failed at: ', anURL] }
774
+ ! !
775
+
776
+ !Browser methodsFor: 'rendering'!
777
+
778
+ renderBoxOn: html
779
+ self
780
+ renderTopPanelOn: html;
781
+ renderTabsOn: html;
782
+ renderBottomPanelOn: html
783
+ !
784
+
785
+ renderTopPanelOn: html
786
+ html div
787
+ class: 'top';
788
+ with: [
789
+ packagesList := html ul class: 'jt_column browser packages'.
790
+ html div class: 'jt_packagesButtons'; with: [
791
+ html button
792
+ title: 'Commit classes in this package to disk';
793
+ onClick: [self commitPackage];
794
+ with: 'Commit'.
795
+ html button
796
+ title: 'Rename package';
797
+ onClick: [self renamePackage];
798
+ with: 'Rename'.
799
+ html button
800
+ title: 'Remove this package from the system';
801
+ onClick: [self removePackage];
802
+ with: 'Remove'].
803
+ classesList := ClassesList on: self.
804
+ classesList renderOn: html.
805
+ protocolsList := html ul class: 'jt_column browser protocols'.
806
+ methodsList := html ul class: 'jt_column browser methods'.
807
+ self
808
+ updateCategoriesList;
809
+ updateClassesList;
810
+ updateProtocolsList;
811
+ updateMethodsList.
812
+ html div class: 'jt_clear']
813
+ !
814
+
815
+ renderTabsOn: html
816
+ tabsList := html ul class: 'jt_tabs jt_browser'.
817
+ self updateTabsList.
818
+ !
819
+
820
+ renderBottomPanelOn: html
821
+ html div
822
+ class: 'jt_sourceCode';
823
+ with: [
824
+ sourceArea := SourceArea new.
825
+ sourceArea renderOn: html.
826
+ sourceArea onKeyDown: [:e |
827
+ self handleSourceAreaKeyDown: e].
828
+ sourceArea onKeyUp: [self updateStatus]]
829
+ !
830
+
831
+ renderButtonsOn: html
832
+ saveButton := html button.
833
+ saveButton
834
+ with: 'Save';
835
+ onClick: [self compile].
836
+ methodButtons := html span.
837
+ classButtons := html span.
838
+ html div
839
+ class: 'right';
840
+ with: [
841
+ html button
842
+ with: 'DoIt';
843
+ onClick: [sourceArea doIt].
844
+ html button
845
+ with: 'PrintIt';
846
+ onClick: [sourceArea printIt].
847
+ html button with: 'InspectIt';
848
+ onClick: [sourceArea inspectIt]].
849
+ self updateSourceAndButtons
850
+ ! !
851
+
852
+ !Browser methodsFor: 'testing'!
853
+
854
+ canBeClosed
855
+ ^true
856
+ ! !
857
+
858
+ !Browser methodsFor: 'updating'!
859
+
860
+ updateCategoriesList
861
+ packagesList contents: [:html |
862
+ self packages do: [:each || li label |
863
+ each isEmpty
864
+ ifTrue: [label := 'Unclassified']
865
+ ifFalse: [label := each].
866
+ li := html li.
867
+ selectedPackage = each ifTrue: [
868
+ li class: 'selected'].
869
+ li
870
+ with: label;
871
+ onClick: [self selectCategory: each]]]
872
+ !
873
+
874
+ updateClassesList
875
+ TabManager current update.
876
+ classesList updateNodes
877
+ !
878
+
879
+ updateProtocolsList
880
+ protocolsList contents: [:html |
881
+ self protocols do: [:each || li |
882
+ li := html li.
883
+ selectedProtocol = each ifTrue: [
884
+ li class: 'selected'].
885
+ li
886
+ with: each;
887
+ onClick: [self selectProtocol: each]]]
888
+ !
889
+
890
+ updateMethodsList
891
+ methodsList contents: [:html |
892
+ self methods do: [:each || li |
893
+ li := html li.
894
+ selectedMethod = each ifTrue: [
895
+ li class: 'selected'].
896
+ li
897
+ with: each selector;
898
+ onClick: [self selectMethod: each]]]
899
+ !
900
+
901
+ updateTabsList
902
+ tabsList contents: [:html || li |
903
+ li := html li.
904
+ selectedTab = #instance ifTrue: [li class: 'selected'].
905
+ li
906
+ with: [
907
+ html span class: 'ltab'.
908
+ html span class: 'mtab'; with: 'Instance'.
909
+ html span class: 'rtab'];
910
+ onClick: [self selectTab: #instance].
911
+ li := html li.
912
+ selectedTab = #class ifTrue: [li class: 'selected'].
913
+ li
914
+ with: [
915
+ html span class: 'ltab'.
916
+ html span class: 'mtab'; with: 'Class'.
917
+ html span class: 'rtab'];
918
+ onClick: [self selectTab: #class].
919
+ li := html li.
920
+ selectedTab = #comment ifTrue: [li class: 'selected'].
921
+ li
922
+ with: [
923
+ html span class: 'ltab'.
924
+ html span class: 'mtab'; with: 'Comment'.
925
+ html span class: 'rtab'];
926
+ onClick: [self selectTab: #comment]]
927
+ !
928
+
929
+ updateSourceAndButtons
930
+ self disableSaveButton.
931
+ classButtons contents: [:html |
932
+ html button
933
+ title: 'Create a new class';
934
+ onClick: [self addNewClass];
935
+ with: 'New class'.
936
+ html button
937
+ with: 'Rename class';
938
+ onClick: [self renameClass].
939
+ html button
940
+ with: 'Copy class';
941
+ onClick: [self copyClass].
942
+ html button
943
+ with: 'Remove class';
944
+ onClick: [self removeClass].
945
+ html button
946
+ with: 'References';
947
+ onClick: [self searchClassReferences]].
948
+ methodButtons contents: [:html | | protocolSelect referencesSelect |
949
+ html button
950
+ with: 'Remove method';
951
+ onClick: [self removeMethod].
952
+ protocolSelect := html select.
953
+ protocolSelect
954
+ onChange: [ self setMethodProtocol: protocolSelect asJQuery val];
955
+ with: [
956
+ html option
957
+ with: 'Method protocol';
958
+ at: 'disabled' put: 'disabled'.
959
+ html option
960
+ class: 'important';
961
+ with: 'New...'.
962
+ self protocols do: [:each |
963
+ html option with: each]].
964
+ selectedMethod isNil ifFalse: [
965
+ referencesSelect := html select.
966
+ referencesSelect
967
+ onChange: [self searchReferencesOf: referencesSelect asJQuery val];
968
+ with: [
969
+ html option
970
+ with: 'References';
971
+ at: 'disabled' put: 'disabled'.
972
+ html option
973
+ class: 'important';
974
+ with: selectedMethod selector.
975
+ selectedMethod messageSends sorted do: [:each |
976
+ html option with: each]]]].
977
+ selectedMethod isNil
978
+ ifTrue: [
979
+ self hideMethodButtons.
980
+ (selectedClass isNil or: [selectedProtocol notNil])
981
+ ifTrue: [self hideClassButtons]
982
+ ifFalse: [self showClassButtons]]
983
+ ifFalse: [
984
+ self hideClassButtons.
985
+ self showMethodButtons].
986
+ sourceArea val: self source
987
+ !
988
+
989
+ updateStatus
990
+ sourceArea val = self source
991
+ ifTrue: [
992
+ saveButton ifNotNil: [
993
+ saveButton at: 'disabled' put: true].
994
+ unsavedChanges := false]
995
+ ifFalse: [
996
+ saveButton ifNotNil: [
997
+ saveButton removeAt: 'disabled'].
998
+ unsavedChanges := true]
999
+ !
1000
+
1001
+ resetClassesList
1002
+ classesList resetNodes
1003
+ ! !
1004
+
1005
+ !Browser class methodsFor: 'accessing'!
1006
+
1007
+ commitPathJs
1008
+ ^'js'
1009
+ !
1010
+
1011
+ commitPathSt
1012
+ ^'st'
1013
+ ! !
1014
+
1015
+ !Browser class methodsFor: 'convenience'!
1016
+
1017
+ openOn: aClass
1018
+ ^self new
1019
+ open;
1020
+ selectCategory: aClass category;
1021
+ selectClass: aClass
1022
+ !
1023
+
1024
+ open
1025
+ self new open
1026
+ ! !
1027
+
1028
+ TabWidget subclass: #Inspector
1029
+ instanceVariableNames: 'label variables object selectedVariable variablesList valueTextarea diveButton sourceArea'
1030
+ category: 'IDE'!
1031
+
1032
+ !Inspector methodsFor: 'accessing'!
1033
+
1034
+ label
1035
+ ^label ifNil: ['Inspector (nil)']
1036
+ !
1037
+
1038
+ variables
1039
+ ^variables
1040
+ !
1041
+
1042
+ setVariables: aCollection
1043
+ variables := aCollection
1044
+ !
1045
+
1046
+ setLabel: aString
1047
+ label := aString
1048
+ !
1049
+
1050
+ selectedVariable
1051
+ ^selectedVariable
1052
+ !
1053
+
1054
+ selectedVariable: aString
1055
+ selectedVariable := aString
1056
+ !
1057
+
1058
+ sourceArea
1059
+ ^sourceArea
1060
+ ! !
1061
+
1062
+ !Inspector methodsFor: 'actions'!
1063
+
1064
+ inspect: anObject
1065
+ object := anObject.
1066
+ variables := #().
1067
+ object inspectOn: self
1068
+ !
1069
+
1070
+ dive
1071
+ (self variables at: self selectedVariable) inspect
1072
+ !
1073
+
1074
+ refresh
1075
+ self
1076
+ inspect: object;
1077
+ updateVariablesList;
1078
+ updateValueTextarea
1079
+ ! !
1080
+
1081
+ !Inspector methodsFor: 'rendering'!
1082
+
1083
+ renderBoxOn: html
1084
+ self
1085
+ renderTopPanelOn: html;
1086
+ renderBottomPanelOn: html
1087
+ !
1088
+
1089
+ renderTopPanelOn: html
1090
+ html div
1091
+ class: 'top';
1092
+ with: [
1093
+ variablesList := html ul class: 'jt_column variables'.
1094
+ valueTextarea := html textarea class: 'jt_column value'; at: 'readonly' put: 'readonly'.
1095
+ html div class: 'jt_tabs inspector'; with: [
1096
+ html button
1097
+ class: 'jt_button inspector refresh';
1098
+ with: 'Refresh';
1099
+ onClick: [self refresh].
1100
+ diveButton := html button
1101
+ class: 'jt_button inspector dive';
1102
+ with: 'Dive';
1103
+ onClick: [self dive]].
1104
+ html div class: 'jt_clear'].
1105
+ self
1106
+ updateVariablesList;
1107
+ updateValueTextarea.
1108
+ !
1109
+
1110
+ renderBottomPanelOn: html
1111
+ html div
1112
+ class: 'jt_sourceCode';
1113
+ with: [
1114
+ sourceArea := SourceArea new
1115
+ receiver: object;
1116
+ onDoIt: [self refresh];
1117
+ yourself.
1118
+ sourceArea renderOn: html]
1119
+ !
1120
+
1121
+ renderButtonsOn: html
1122
+ html button
1123
+ with: 'DoIt';
1124
+ onClick: [self sourceArea doIt].
1125
+ html button
1126
+ with: 'PrintIt';
1127
+ onClick: [self sourceArea printIt].
1128
+ html button
1129
+ with: 'InspectIt';
1130
+ onClick: [self sourceArea inspectIt].
1131
+ self updateButtons
1132
+ ! !
1133
+
1134
+ !Inspector methodsFor: 'testing'!
1135
+
1136
+ canBeClosed
1137
+ ^true
1138
+ ! !
1139
+
1140
+ !Inspector methodsFor: 'updating'!
1141
+
1142
+ updateVariablesList
1143
+ variablesList contents: [:html |
1144
+ self variables keys do: [:each || li |
1145
+ li := html li.
1146
+ li
1147
+ with: each;
1148
+ onClick: [self selectVariable: each].
1149
+ self selectedVariable = each ifTrue: [
1150
+ li class: 'selected']]]
1151
+ !
1152
+
1153
+ selectVariable: aString
1154
+ self selectedVariable: aString.
1155
+ self
1156
+ updateVariablesList;
1157
+ updateValueTextarea;
1158
+ updateButtons
1159
+ !
1160
+
1161
+ updateValueTextarea
1162
+ valueTextarea asJQuery val: (self selectedVariable isNil
1163
+ ifTrue: ['']
1164
+ ifFalse: [(self variables at: self selectedVariable) printString])
1165
+ !
1166
+
1167
+ updateButtons
1168
+ (self selectedVariable notNil and: [(self variables at: self selectedVariable) notNil])
1169
+ ifFalse: [diveButton at: 'disabled' put: true]
1170
+ ifTrue: [diveButton removeAt: 'disabled']
1171
+ ! !
1172
+
1173
+ !Inspector class methodsFor: 'instance creation'!
1174
+
1175
+ on: anObject
1176
+ ^self new
1177
+ inspect: anObject;
1178
+ yourself
1179
+ ! !
1180
+
1181
+ TabWidget subclass: #ReferencesBrowser
1182
+ instanceVariableNames: 'implementors senders implementorsList input timer selector sendersList referencedClasses referencedClassesList'
1183
+ category: 'IDE'!
1184
+
1185
+ !ReferencesBrowser methodsFor: 'accessing'!
1186
+
1187
+ implementors
1188
+ ^implementors ifNil: [implementors := Array new]
1189
+ !
1190
+
1191
+ label
1192
+ ^'[References]'
1193
+ !
1194
+
1195
+ selector
1196
+ ^selector
1197
+ !
1198
+
1199
+ senders
1200
+ ^senders ifNil: [senders := Array new]
1201
+ !
1202
+
1203
+ classesAndMetaclasses
1204
+ ^Smalltalk current classes, (Smalltalk current classes collect: [:each | each class])
1205
+ !
1206
+
1207
+ referencedClasses
1208
+ ^referencedClasses ifNil: [referencedClasses := Array new]
1209
+ ! !
1210
+
1211
+ !ReferencesBrowser methodsFor: 'actions'!
1212
+
1213
+ openBrowserOn: aMethod
1214
+ | browser |
1215
+ browser := Browser openOn: (aMethod methodClass isMetaclass
1216
+ ifTrue: [aMethod methodClass instanceClass] ifFalse: [aMethod methodClass]).
1217
+ aMethod methodClass isMetaclass ifTrue: [browser selectTab: #class].
1218
+ browser
1219
+ selectProtocol: aMethod category;
1220
+ selectMethod: aMethod
1221
+ !
1222
+
1223
+ searchReferencesFor: aString
1224
+ selector := aString.
1225
+ implementors := Array new.
1226
+ senders := Array new.
1227
+ referencedClasses := Array new.
1228
+ (selector match: '^[A-Z]')
1229
+ ifFalse: [self searchSelectorReferencesFor: selector]
1230
+ ifTrue: [self searchReferencedClassesFor: selector]
1231
+ !
1232
+
1233
+ search: aString
1234
+ self
1235
+ searchReferencesFor: aString;
1236
+ updateImplementorsList;
1237
+ updateSendersList;
1238
+ updateReferencedClassesList
1239
+ !
1240
+
1241
+ searchReferencedClassesFor: aString
1242
+ self classesAndMetaclasses do: [:each |
1243
+ each methodDictionary values do: [:value |
1244
+ (value referencedClasses includes: selector) ifTrue: [
1245
+ self referencedClasses add: value]]]
1246
+ !
1247
+
1248
+ searchSelectorReferencesFor: aString
1249
+ self classesAndMetaclasses do: [:each |
1250
+ each methodDictionary keysAndValuesDo: [:key :value |
1251
+ key = selector ifTrue: [self implementors add: value].
1252
+ (value messageSends includes: selector) ifTrue: [
1253
+ self senders add: value]]]
1254
+ ! !
1255
+
1256
+ !ReferencesBrowser methodsFor: 'initialization'!
1257
+
1258
+ initialize
1259
+ super initialize.
1260
+ selector := ''
1261
+ ! !
1262
+
1263
+ !ReferencesBrowser methodsFor: 'private'!
1264
+
1265
+ setInputEvents
1266
+ input
1267
+ onKeyUp: [timer := [self search: input asJQuery val] valueWithTimeout: 100];
1268
+ onKeyDown: [timer ifNotNil: [timer clearTimeout]]
1269
+ ! !
1270
+
1271
+ !ReferencesBrowser methodsFor: 'rendering'!
1272
+
1273
+ renderBoxOn: html
1274
+ self
1275
+ renderInputOn: html;
1276
+ renderImplementorsOn: html;
1277
+ renderSendersOn: html;
1278
+ renderReferencedClassesOn: html
1279
+ !
1280
+
1281
+ renderInputOn: html
1282
+ input := html input
1283
+ class: 'implementors';
1284
+ yourself.
1285
+ input asJQuery val: selector.
1286
+ self setInputEvents
1287
+ !
1288
+
1289
+ renderImplementorsOn: html
1290
+ implementorsList := html ul class: 'jt_column implementors'.
1291
+ self updateImplementorsList
1292
+ !
1293
+
1294
+ renderSendersOn: html
1295
+ sendersList := html ul class: 'jt_column senders'.
1296
+ self updateSendersList
1297
+ !
1298
+
1299
+ renderReferencedClassesOn: html
1300
+ referencedClassesList := html ul class: 'jt_column referenced_classes'.
1301
+ self updateReferencedClassesList
1302
+ ! !
1303
+
1304
+ !ReferencesBrowser methodsFor: 'testing'!
1305
+
1306
+ canBeClosed
1307
+ ^true
1308
+ ! !
1309
+
1310
+ !ReferencesBrowser methodsFor: 'updating'!
1311
+
1312
+ updateImplementorsList
1313
+ implementorsList contents: [:html |
1314
+ html li
1315
+ class: 'column_label';
1316
+ with: 'Implementors (', self implementors size asString, ')';
1317
+ style: 'font-weight: bold'.
1318
+ self implementors do: [:each || li |
1319
+ li := html li.
1320
+ li
1321
+ with: (each methodClass asString, ' >> ', self selector);
1322
+ onClick: [self openBrowserOn: each]]]
1323
+ !
1324
+
1325
+ updateSendersList
1326
+ sendersList contents: [:html |
1327
+ html li
1328
+ class: 'column_label';
1329
+ with: 'Senders (', self senders size asString, ')';
1330
+ style: 'font-weight: bold'.
1331
+ self senders do: [:each |
1332
+ html li
1333
+ with: (each methodClass asString, ' >> ', each selector);
1334
+ onClick: [self openBrowserOn: each]]]
1335
+ !
1336
+
1337
+ updateReferencedClassesList
1338
+ referencedClassesList contents: [:html |
1339
+ html li
1340
+ class: 'column_label';
1341
+ with: 'Class references (', self referencedClasses size asString, ')';
1342
+ style: 'font-weight: bold'.
1343
+ self referencedClasses do: [:each |
1344
+ html li
1345
+ with: (each methodClass asString, ' >> ', each selector);
1346
+ onClick: [self openBrowserOn: each]]]
1347
+ ! !
1348
+
1349
+ !ReferencesBrowser class methodsFor: 'instance creation'!
1350
+
1351
+ search: aString
1352
+ ^self new
1353
+ searchReferencesFor: aString;
1354
+ open
1355
+ ! !
1356
+
1357
+ Widget subclass: #SourceArea
1358
+ instanceVariableNames: 'editor div receiver onDoIt'
1359
+ category: 'IDE'!
1360
+
1361
+ !SourceArea methodsFor: 'accessing'!
1362
+
1363
+ val
1364
+ ^editor getValue
1365
+ !
1366
+
1367
+ val: aString
1368
+ editor setValue: aString
1369
+ !
1370
+
1371
+ currentLine
1372
+ ^editor getLine: (editor getCursor line)
1373
+ !
1374
+
1375
+ selection
1376
+ ^editor getSelection
1377
+ !
1378
+
1379
+ selectionEnd
1380
+ ^textarea element selectionEnd
1381
+ !
1382
+
1383
+ selectionStart
1384
+ ^textarea element selectionStart
1385
+ !
1386
+
1387
+ selectionStart: anInteger
1388
+ textarea element selectionStart: anInteger
1389
+ !
1390
+
1391
+ selectionEnd: anInteger
1392
+ textarea element selectionEnd: anInteger
1393
+ !
1394
+
1395
+ setEditorOn: aTextarea
1396
+ <self['@editor'] = CodeMirror.fromTextArea(aTextarea, {
1397
+ theme: 'jtalk',
1398
+ lineNumbers: true,
1399
+ enterMode: 'flat',
1400
+ matchBrackets: true,
1401
+ electricChars: false
1402
+ })>
1403
+ !
1404
+
1405
+ editor
1406
+ ^editor
1407
+ !
1408
+
1409
+ receiver
1410
+ ^receiver ifNil: [DoIt new]
1411
+ !
1412
+
1413
+ receiver: anObject
1414
+ receiver := anObject
1415
+ !
1416
+
1417
+ onDoIt: aBlock
1418
+ onDoIt := aBlock
1419
+ !
1420
+
1421
+ onDoIt
1422
+ ^onDoIt
1423
+ !
1424
+
1425
+ currentLineOrSelection
1426
+ ^editor somethingSelected
1427
+ ifFalse: [self currentLine]
1428
+ ifTrue: [self selection]
1429
+ ! !
1430
+
1431
+ !SourceArea methodsFor: 'actions'!
1432
+
1433
+ clear
1434
+ self val: ''
1435
+ !
1436
+
1437
+ doIt
1438
+ | result |
1439
+ result := self eval: self currentLineOrSelection.
1440
+ self onDoIt ifNotNil: [self onDoIt value].
1441
+ ^result
1442
+ !
1443
+
1444
+ eval: aString
1445
+ | compiler |
1446
+ compiler := Compiler new.
1447
+ [compiler parseExpression: aString] on: Error do: [:ex |
1448
+ ^window alert: ex messageText].
1449
+ ^(compiler load: 'doIt ^[', aString, '] value' forClass: DoIt) fn applyTo: self receiver arguments: #()
1450
+ !
1451
+
1452
+ handleKeyDown: anEvent
1453
+ <if(anEvent.ctrlKey) {
1454
+ if(anEvent.keyCode === 80) { //ctrl+p
1455
+ self._printIt();
1456
+ anEvent.preventDefault();
1457
+ return false;
1458
+ }
1459
+ if(anEvent.keyCode === 68) { //ctrl+d
1460
+ self._doIt();
1461
+ anEvent.preventDefault();
1462
+ return false;
1463
+ }
1464
+ if(anEvent.keyCode === 73) { //ctrl+i
1465
+ self._inspectIt();
1466
+ anEvent.preventDefault();
1467
+ return false;
1468
+ }
1469
+ }>
1470
+ !
1471
+
1472
+ inspectIt
1473
+ self doIt inspect
1474
+ !
1475
+
1476
+ print: aString
1477
+ | start stop |
1478
+ start := HashedCollection new.
1479
+ stop := HashedCollection new.
1480
+ start at: 'line' put: (editor getCursor: false) line.
1481
+ start at: 'ch' put: (editor getCursor: false) ch.
1482
+ stop at: 'line' put: (start at: 'line').
1483
+ stop at: 'ch' put: ((start at: 'ch') + aString size + 2).
1484
+ editor replaceSelection: (editor getSelection, ' ', aString, ' ').
1485
+ editor setCursor: (editor getCursor: true).
1486
+ editor setSelection: stop end: start
1487
+ !
1488
+
1489
+ printIt
1490
+ self print: self doIt printString
1491
+ !
1492
+
1493
+ fileIn
1494
+ Importer new import: self currentLineOrSelection readStream
1495
+ ! !
1496
+
1497
+ !SourceArea methodsFor: 'events'!
1498
+
1499
+ onKeyUp: aBlock
1500
+ div onKeyUp: aBlock
1501
+ !
1502
+
1503
+ onKeyDown: aBlock
1504
+ div onKeyDown: aBlock
1505
+ ! !
1506
+
1507
+ !SourceArea methodsFor: 'rendering'!
1508
+
1509
+ renderOn: html
1510
+ | textarea |
1511
+ div := html div class: 'source'.
1512
+ div with: [textarea := html textarea].
1513
+ self setEditorOn: textarea element.
1514
+ div onKeyDown: [:e | self handleKeyDown: e]
1515
+ ! !
1516
+
1517
+ Widget subclass: #ClassesList
1518
+ instanceVariableNames: 'browser ul nodes'
1519
+ category: 'IDE'!
1520
+
1521
+ !ClassesList methodsFor: 'accessing'!
1522
+
1523
+ category
1524
+ ^self browser selectedPackage
1525
+ !
1526
+
1527
+ nodes
1528
+ nodes ifNil: [nodes := self getNodes].
1529
+ ^nodes
1530
+ !
1531
+
1532
+ browser
1533
+ ^browser
1534
+ !
1535
+
1536
+ browser: aBrowser
1537
+ browser := aBrowser
1538
+ !
1539
+
1540
+ getNodes
1541
+ | classes children others |
1542
+ classes := self browser classes.
1543
+ children := #().
1544
+ others := #().
1545
+ classes do: [:each |
1546
+ (classes includes: each superclass)
1547
+ ifFalse: [children add: each]
1548
+ ifTrue: [others add: each]].
1549
+ ^children collect: [:each |
1550
+ ClassesListNode on: each browser: self browser classes: others level: 0]
1551
+ !
1552
+
1553
+ resetNodes
1554
+ nodes := nil
1555
+ ! !
1556
+
1557
+ !ClassesList methodsFor: 'rendering'!
1558
+
1559
+ renderOn: html
1560
+ ul := html ul
1561
+ class: 'jt_column browser classes';
1562
+ yourself.
1563
+ self updateNodes
1564
+ !
1565
+
1566
+ updateNodes
1567
+ ul contents: [:html |
1568
+ self nodes do: [:each |
1569
+ each renderOn: html]]
1570
+ ! !
1571
+
1572
+ !ClassesList class methodsFor: 'instance creation'!
1573
+
1574
+ on: aBrowser
1575
+ ^self new
1576
+ browser: aBrowser;
1577
+ yourself
1578
+ ! !
1579
+
1580
+ Widget subclass: #ClassesListNode
1581
+ instanceVariableNames: 'browser theClass level nodes'
1582
+ category: 'IDE'!
1583
+
1584
+ !ClassesListNode methodsFor: ''!
1585
+
1586
+ renderOn: html
1587
+ | li cssClass |
1588
+ cssClass := ''.
1589
+ li := html li
1590
+ onClick: [self browser selectClass: self theClass].
1591
+ li asJQuery html: self label.
1592
+
1593
+ self browser selectedClass = self theClass ifTrue: [
1594
+ cssClass := cssClass, ' selected'].
1595
+
1596
+ self theClass comment isEmpty ifFalse: [
1597
+ cssClass := cssClass, ' commented'].
1598
+
1599
+ li class: cssClass.
1600
+
1601
+ self nodes do: [:each |
1602
+ each renderOn: html]
1603
+ ! !
1604
+
1605
+ !ClassesListNode methodsFor: 'accessing'!
1606
+
1607
+ nodes
1608
+ ^nodes
1609
+ !
1610
+
1611
+ theClass
1612
+ ^theClass
1613
+ !
1614
+
1615
+ theClass: aClass
1616
+ theClass := aClass
1617
+ !
1618
+
1619
+ browser
1620
+ ^browser
1621
+ !
1622
+
1623
+ browser: aBrowser
1624
+ browser := aBrowser
1625
+ !
1626
+
1627
+ level
1628
+ ^level
1629
+ !
1630
+
1631
+ level: anInteger
1632
+ level := anInteger
1633
+ !
1634
+
1635
+ label
1636
+ | str |
1637
+ str := String new writeStream.
1638
+ self level timesRepeat: [
1639
+ str nextPutAll: '&nbsp;&nbsp;&nbsp;&nbsp;'].
1640
+ str nextPutAll: self theClass name.
1641
+ ^str contents
1642
+ !
1643
+
1644
+ getNodesFrom: aCollection
1645
+ | children others |
1646
+ children := #().
1647
+ others := #().
1648
+ aCollection do: [:each |
1649
+ (each superclass = self theClass)
1650
+ ifTrue: [children add: each]
1651
+ ifFalse: [others add: each]].
1652
+ nodes:= children collect: [:each |
1653
+ ClassesListNode on: each browser: self browser classes: others level: self level + 1]
1654
+ ! !
1655
+
1656
+ !ClassesListNode class methodsFor: 'instance creation'!
1657
+
1658
+ on: aClass browser: aBrowser classes: aCollection level: anInteger
1659
+ ^self new
1660
+ theClass: aClass;
1661
+ browser: aBrowser;
1662
+ level: anInteger;
1663
+ getNodesFrom: aCollection;
1664
+ yourself
1665
+ ! !
1666
+
1667
+ TabWidget subclass: #Debugger
1668
+ instanceVariableNames: 'error selectedContext sourceArea ul ul2 inspector saveButton unsavedChanges selectedVariable selectedVariableName inspectButton'
1669
+ category: 'IDE'!
1670
+
1671
+ !Debugger methodsFor: 'accessing'!
1672
+
1673
+ error
1674
+ ^error
1675
+ !
1676
+
1677
+ error: anError
1678
+ error := anError
1679
+ !
1680
+
1681
+ label
1682
+ ^'[Debugger]'
1683
+ !
1684
+
1685
+ source
1686
+ ^self method
1687
+ ifNil: ['Method doesn''t exist!!']
1688
+ ifNotNil: [self method source]
1689
+ !
1690
+
1691
+ method
1692
+ ^selectedContext receiver class methodAt: selectedContext selector
1693
+ !
1694
+
1695
+ arguments
1696
+ ^self method
1697
+ ifNil: [selectedContext temps collect: [:each | nil]]
1698
+ ifNotNil: [self method arguments]
1699
+ !
1700
+
1701
+ receiver
1702
+ ^selectedContext receiver
1703
+ ! !
1704
+
1705
+ !Debugger methodsFor: 'actions'!
1706
+
1707
+ selectContext: aContext
1708
+ selectedContext := aContext.
1709
+ selectedVariable := nil.
1710
+ selectedVariableName := nil.
1711
+ self
1712
+ updateContextsList;
1713
+ updateSourceArea;
1714
+ updateInspector;
1715
+ updateVariablesList;
1716
+ updateStatus
1717
+ !
1718
+
1719
+ proceed
1720
+ self close.
1721
+ selectedContext receiver perform: selectedContext selector withArguments: selectedContext temps
1722
+ !
1723
+
1724
+ save
1725
+ | protocol |
1726
+ protocol := (selectedContext receiver class methodDictionary at: selectedContext selector) category.
1727
+ selectedContext receiver class compile: sourceArea val category: protocol.
1728
+ self updateStatus
1729
+ !
1730
+
1731
+ selectVariable: anObject named: aString
1732
+ selectedVariable := anObject.
1733
+ selectedVariableName := aString.
1734
+ inspector contents: [:html | html with: anObject printString].
1735
+ self updateVariablesList
1736
+ !
1737
+
1738
+ inspectSelectedVariable
1739
+ selectedVariable inspect
1740
+ ! !
1741
+
1742
+ !Debugger methodsFor: 'initialization'!
1743
+
1744
+ initialize
1745
+ super initialize.
1746
+ unsavedChanges = false
1747
+ ! !
1748
+
1749
+ !Debugger methodsFor: 'rendering'!
1750
+
1751
+ renderTopPanelOn: html
1752
+ selectedContext := self error context.
1753
+ html div
1754
+ class: 'top';
1755
+ with: [
1756
+ html div
1757
+ class: 'label';
1758
+ with: self error messageText.
1759
+ ul := html ul
1760
+ class: 'jt_column debugger contexts';
1761
+ with: [self renderContext: self error context on: html]]
1762
+ !
1763
+
1764
+ renderContext: aContext on: html
1765
+ | li |
1766
+ li := html li.
1767
+ selectedContext = aContext ifTrue: [
1768
+ li class: 'selected'].
1769
+ li
1770
+ with: aContext asString;
1771
+ onClick: [self selectContext: aContext].
1772
+ aContext home ifNotNil: [self renderContext: aContext home on: html]
1773
+ !
1774
+
1775
+ renderBottomPanelOn: html
1776
+ html div
1777
+ class: 'jt_sourceCode debugger';
1778
+ with: [
1779
+ sourceArea := SourceArea new.
1780
+ sourceArea renderOn: html].
1781
+ ul2 := html ul class: 'jt_column debugger variables'.
1782
+ inspector := html div class: 'jt_column debugger inspector'.
1783
+ sourceArea
1784
+ onKeyUp: [self updateStatus]
1785
+ !
1786
+
1787
+ renderButtonsOn: html
1788
+ saveButton := html button
1789
+ with: 'Save';
1790
+ onClick: [self save].
1791
+ html button
1792
+ with: 'DoIt';
1793
+ onClick: [sourceArea doIt].
1794
+ html button
1795
+ with: 'PrintIt';
1796
+ onClick: [sourceArea printIt].
1797
+ html button
1798
+ with: 'InspectIt';
1799
+ onClick: [sourceArea inspectIt].
1800
+ html button
1801
+ with: 'Proceed';
1802
+ onClick: [self proceed].
1803
+ html button
1804
+ with: 'Abandon';
1805
+ onClick: [self close].
1806
+ inspectButton := html button
1807
+ class: 'jt_button debugger inspect';
1808
+ with: 'Inspect';
1809
+ onClick: [self inspectSelectedVariable].
1810
+ self
1811
+ updateSourceArea;
1812
+ updateStatus;
1813
+ updateVariablesList;
1814
+ updateInspector
1815
+ !
1816
+
1817
+ renderBoxOn: html
1818
+ self
1819
+ renderTopPanelOn: html;
1820
+ renderBottomPanelOn: html
1821
+ ! !
1822
+
1823
+ !Debugger methodsFor: 'testing'!
1824
+
1825
+ canBeClosed
1826
+ ^true
1827
+ ! !
1828
+
1829
+ !Debugger methodsFor: 'updating'!
1830
+
1831
+ updateContextsList
1832
+ ul contents: [:html |
1833
+ self renderContext: self error context on: html]
1834
+ !
1835
+
1836
+ updateSourceArea
1837
+ sourceArea val: self source
1838
+ !
1839
+
1840
+ updateStatus
1841
+ sourceArea val = self source
1842
+ ifTrue: [
1843
+ saveButton ifNotNil: [
1844
+ saveButton at: 'disabled' put: true].
1845
+ unsavedChanges := false]
1846
+ ifFalse: [
1847
+ saveButton ifNotNil: [
1848
+ saveButton removeAt: 'disabled'].
1849
+ unsavedChanges := true]
1850
+ !
1851
+
1852
+ updateInspector
1853
+ inspector contents: [:html |]
1854
+ !
1855
+
1856
+ updateVariablesList
1857
+ ul2 contents: [:html | | li |
1858
+ li := html li
1859
+ with: 'self';
1860
+ onClick: [self selectVariable: self receiver named: 'self'].
1861
+ selectedVariableName = 'self' ifTrue: [
1862
+ li class: 'selected'].
1863
+ self arguments withIndexDo: [:each :index | | param |
1864
+ param := selectedContext temps at: index.
1865
+ li := html li
1866
+ with: each;
1867
+ onClick: [self selectVariable: param named: each].
1868
+ selectedVariableName = each ifTrue: [
1869
+ li class: 'selected']].
1870
+ self receiver class allInstanceVariableNames do: [:each | | ivar |
1871
+ ivar := self receiver instVarAt: each.
1872
+ li := html li
1873
+ with: each;
1874
+ onClick: [self selectVariable: ivar named: each].
1875
+ selectedVariableName = each ifTrue: [
1876
+ li class: 'selected']]].
1877
+ selectedVariable ifNil: [inspectButton at: 'disabled' put: true] ifNotNil: [inspectButton removeAt: 'disabled']
1878
+ ! !
1879
+
1880
+ ErrorHandler subclass: #DebugErrorHandler
1881
+ instanceVariableNames: ''
1882
+ category: 'IDE'!
1883
+
1884
+ !DebugErrorHandler methodsFor: 'error handling'!
1885
+
1886
+ handleError: anError
1887
+ [Debugger new
1888
+ error: anError;
1889
+ open] on: Error do: [:error |
1890
+ ErrorHandler new handleError: error]
1891
+ ! !
1892
+
1893
+ !DebugErrorHandler class methodsFor: 'initialization'!
1894
+
1895
+ initialize
1896
+ self register
1897
+ ! !
1898
+
1899
+ TabWidget subclass: #ProgressBar
1900
+ instanceVariableNames: 'percent progressDiv div'
1901
+ category: 'IDE'!
1902
+
1903
+ !ProgressBar methodsFor: 'accessing'!
1904
+
1905
+ percent
1906
+ ^percent ifNil: [0]
1907
+ !
1908
+
1909
+ percent: aNumber
1910
+ percent := aNumber
1911
+ ! !
1912
+
1913
+ !ProgressBar methodsFor: 'rendering'!
1914
+
1915
+ renderOn: html
1916
+ div := html div
1917
+ class: 'progress_bar';
1918
+ yourself.
1919
+ self renderProgressBar
1920
+ !
1921
+
1922
+ renderProgressBar
1923
+ div contents: [:html |
1924
+ html div
1925
+ class: 'progress';
1926
+ style: 'width:', self percent asString, '%']
1927
+ ! !
1928
+
1929
+ !ProgressBar methodsFor: 'updating'!
1930
+
1931
+ updatePercent: aNumber
1932
+ self percent: aNumber.
1933
+ self renderProgressBar
1934
+ ! !
1935
+
1936
+ TabWidget subclass: #TestRunner
1937
+ instanceVariableNames: 'selectedCategories packagesList selectedClasses classesList selectedMethods progressBar methodsList result statusDiv'
1938
+ category: 'IDE'!
1939
+
1940
+ !TestRunner methodsFor: 'accessing'!
1941
+
1942
+ label
1943
+ ^'SUnit'
1944
+ !
1945
+
1946
+ packages
1947
+ | packages |
1948
+ packages := Array new.
1949
+ self allClasses do: [:each |
1950
+ (packages includes: each category) ifFalse: [
1951
+ packages add: each category]].
1952
+ ^packages sort
1953
+ !
1954
+
1955
+ classes
1956
+ ^(self allClasses
1957
+ select: [:each | self selectedCategories includes: each category])
1958
+ sort: [:a :b | a name > b name]
1959
+ !
1960
+
1961
+ selectedCategories
1962
+ ^selectedCategories ifNil: [selectedCategories := Array new]
1963
+ !
1964
+
1965
+ allClasses
1966
+ ^TestCase allSubclasses
1967
+ !
1968
+
1969
+ selectedClasses
1970
+ ^selectedClasses ifNil: [selectedClasses := Array new]
1971
+ !
1972
+
1973
+ progressBar
1974
+ ^progressBar ifNil: [progressBar := ProgressBar new]
1975
+ !
1976
+
1977
+ statusInfo
1978
+ ^self printTotal, self printPasses, self printErrors, self printFailures
1979
+ !
1980
+
1981
+ result
1982
+ ^result
1983
+ !
1984
+
1985
+ testCases
1986
+ | testCases |
1987
+ testCases := #().
1988
+ self selectedClasses do: [:each | testCases addAll: each buildSuite].
1989
+ ^testCases
1990
+ ! !
1991
+
1992
+ !TestRunner methodsFor: 'actions'!
1993
+
1994
+ selectAllCategories
1995
+ self packages do: [:each |
1996
+ (selectedCategories includes: each) ifFalse: [
1997
+ self selectedCategories add: each]].
1998
+ self
1999
+ updateCategoriesList;
2000
+ updateClassesList
2001
+ !
2002
+
2003
+ toggleCategory: aCategory
2004
+ (self isSelectedCategory: aCategory)
2005
+ ifFalse: [selectedCategories add: aCategory]
2006
+ ifTrue: [selectedCategories remove: aCategory].
2007
+ self
2008
+ updateCategoriesList;
2009
+ updateClassesList
2010
+ !
2011
+
2012
+ toggleClass: aClass
2013
+ (self isSelectedClass: aClass)
2014
+ ifFalse: [selectedClasses add: aClass]
2015
+ ifTrue: [selectedClasses remove: aClass].
2016
+ self
2017
+ updateClassesList
2018
+ !
2019
+
2020
+ selectAllClasses
2021
+ self classes do: [:each |
2022
+ (selectedClasses includes: each) ifFalse: [
2023
+ self selectedClasses add: each]].
2024
+ self
2025
+ updateCategoriesList;
2026
+ updateClassesList
2027
+ !
2028
+
2029
+ run: aCollection
2030
+ result := TestResult new.
2031
+ self
2032
+ updateStatusDiv;
2033
+ updateMethodsList.
2034
+ self progressBar updatePercent: 0.
2035
+ result total: aCollection size.
2036
+ aCollection do: [:each |
2037
+ [each runCaseFor: result.
2038
+ self progressBar updatePercent: result runs / result total * 100.
2039
+ self updateStatusDiv.
2040
+ self updateMethodsList] valueWithTimeout: 100].
2041
+ !
2042
+
2043
+ performFailure: aTestCase
2044
+ aTestCase perform: aTestCase selector
2045
+ ! !
2046
+
2047
+ !TestRunner methodsFor: 'initialization'!
2048
+
2049
+ initialize
2050
+ super initialize.
2051
+ result := TestResult new
2052
+ ! !
2053
+
2054
+ !TestRunner methodsFor: 'printing'!
2055
+
2056
+ printErrors
2057
+ ^self result errors size asString , ' errors, '
2058
+ !
2059
+
2060
+ printFailures
2061
+ ^self result failures size asString, ' failures'
2062
+ !
2063
+
2064
+ printPasses
2065
+ ^(self result total - self result errors size - self result failures size) asString , ' passes, '
2066
+ !
2067
+
2068
+ printTotal
2069
+ ^self result total asString, ' runs, '
2070
+ ! !
2071
+
2072
+ !TestRunner methodsFor: 'rendering'!
2073
+
2074
+ renderBoxOn: html
2075
+ self
2076
+ renderCategoriesOn: html;
2077
+ renderClassesOn: html;
2078
+ renderResultsOn: html
2079
+ !
2080
+
2081
+ renderButtonsOn: html
2082
+ html button
2083
+ with: 'Run selected';
2084
+ onClick: [self run: self testCases]
2085
+ !
2086
+
2087
+ renderCategoriesOn: html
2088
+ packagesList := html ul class: 'jt_column sunit packages'.
2089
+ self updateCategoriesList
2090
+ !
2091
+
2092
+ renderClassesOn: html
2093
+ classesList := html ul class: 'jt_column sunit classes'.
2094
+ self updateClassesList
2095
+ !
2096
+
2097
+ renderResultsOn: html
2098
+ statusDiv := html div.
2099
+ html with: self progressBar.
2100
+ methodsList := html ul class: 'jt_column sunit results'.
2101
+ self updateMethodsList.
2102
+ self updateStatusDiv
2103
+ !
2104
+
2105
+ renderFailuresOn: html
2106
+ self result failures do: [:each |
2107
+ html li
2108
+ class: 'failures';
2109
+ with: each class name, ' >> ', each selector;
2110
+ onClick: [self performFailure: each]]
2111
+ !
2112
+
2113
+ renderErrorsOn: html
2114
+ self result errors do: [:each |
2115
+ html li
2116
+ class: 'errors';
2117
+ with: each class name, ' >> ', each selector;
2118
+ onClick: [self performFailure: each]]
2119
+ ! !
2120
+
2121
+ !TestRunner methodsFor: 'testing'!
2122
+
2123
+ isSelectedClass: aClass
2124
+ ^(self selectedClasses includes: aClass)
2125
+ !
2126
+
2127
+ isSelectedCategory: aCategory
2128
+ ^(self selectedCategories includes: aCategory)
2129
+ ! !
2130
+
2131
+ !TestRunner methodsFor: 'updating'!
2132
+
2133
+ updateCategoriesList
2134
+ packagesList contents: [:html |
2135
+ html li
2136
+ class: 'all';
2137
+ with: 'All';
2138
+ onClick: [self selectAllCategories].
2139
+ self packages do: [:each || li |
2140
+ li := html li.
2141
+ (self selectedCategories includes: each) ifTrue: [
2142
+ li class: 'selected'].
2143
+ li
2144
+ with: each;
2145
+ onClick: [self toggleCategory: each]]]
2146
+ !
2147
+
2148
+ updateClassesList
2149
+ classesList contents: [:html |
2150
+ (self selectedCategories isEmpty) ifFalse: [
2151
+ html li
2152
+ class: 'all';
2153
+ with: 'All';
2154
+ onClick: [self selectAllClasses]].
2155
+ self classes do: [:each || li |
2156
+ li := html li.
2157
+ (self selectedClasses includes: each) ifTrue: [
2158
+ li class: 'selected'].
2159
+ li
2160
+ with: each name;
2161
+ onClick: [self toggleClass: each]]]
2162
+ !
2163
+
2164
+ updateMethodsList
2165
+ methodsList contents: [:html |
2166
+ self renderErrorsOn: html.
2167
+ self renderFailuresOn: html]
2168
+ !
2169
+
2170
+ updateStatusDiv
2171
+ statusDiv class: 'sunit status ', result status.
2172
+ statusDiv contents: [:html |
2173
+ html span with: self statusInfo]
2174
+ ! !
2175
+
2176
+ TabWidget subclass: #IDETranscript
2177
+ instanceVariableNames: 'textarea'
2178
+ category: 'IDE'!
2179
+
2180
+ !IDETranscript methodsFor: 'accessing'!
2181
+
2182
+ label
2183
+ ^'Transcript'
2184
+ ! !
2185
+
2186
+ !IDETranscript methodsFor: 'actions'!
2187
+
2188
+ clear
2189
+ textarea asJQuery val: ''
2190
+ !
2191
+
2192
+ cr
2193
+ textarea asJQuery val: textarea asJQuery val, String cr.
2194
+ !
2195
+
2196
+ show: anObject
2197
+ textarea asJQuery val: textarea asJQuery val, anObject asString.
2198
+ !
2199
+
2200
+ open
2201
+ TabManager current
2202
+ open;
2203
+ selectTab: self
2204
+ ! !
2205
+
2206
+ !IDETranscript methodsFor: 'rendering'!
2207
+
2208
+ renderBoxOn: html
2209
+ textarea := html textarea.
2210
+ textarea
2211
+ class: 'jt_transcript';
2212
+ at: 'spellcheck' put: 'false'
2213
+ !
2214
+
2215
+ renderButtonsOn: html
2216
+ html button
2217
+ with: 'Clear transcript';
2218
+ onClick: [self clear]
2219
+ ! !
2220
+
2221
+ IDETranscript class instanceVariableNames: 'current'!
2222
+
2223
+ !IDETranscript class methodsFor: 'initialization'!
2224
+
2225
+ initialize
2226
+ Transcript register: self current
2227
+ ! !
2228
+
2229
+ !IDETranscript class methodsFor: 'instance creation'!
2230
+
2231
+ new
2232
+ self shouldNotImplement
2233
+ !
2234
+
2235
+ open
2236
+ TabManager current
2237
+ open;
2238
+ selectTab: self current
2239
+ !
2240
+
2241
+ current
2242
+ ^current ifNil: [current := super new]
2243
+ ! !
2244
+
2245
+ !Object methodsFor: '*IDE'!
2246
+
2247
+ inspect
2248
+ Inspector new
2249
+ inspect: self;
2250
+ open
2251
+ !
2252
+
2253
+ inspectOn: anInspector
2254
+ | variables |
2255
+ variables := Dictionary new.
2256
+ variables at: '#self' put: self.
2257
+ self class allInstanceVariableNames do: [:each |
2258
+ variables at: each put: (self instVarAt: each)].
2259
+ anInspector
2260
+ setLabel: self printString;
2261
+ setVariables: variables
2262
+ ! !
2263
+
2264
+ !Date methodsFor: '*IDE'!
2265
+
2266
+ inspectOn: anInspector
2267
+ | variables |
2268
+ variables := Dictionary new.
2269
+ variables at: '#self' put: self.
2270
+ variables at: '#year' put: self year.
2271
+ variables at: '#month' put: self month.
2272
+ variables at: '#day' put: self day.
2273
+ variables at: '#hours' put: self hours.
2274
+ variables at: '#minutes' put: self minutes.
2275
+ variables at: '#seconds' put: self seconds.
2276
+ variables at: '#milliseconds' put: self milliseconds.
2277
+ anInspector
2278
+ setLabel: self printString;
2279
+ setVariables: variables
2280
+ ! !
2281
+
2282
+ !Collection methodsFor: '*IDE'!
2283
+
2284
+ inspectOn: anInspector
2285
+ | variables |
2286
+ variables := Dictionary new.
2287
+ variables at: '#self' put: self.
2288
+ self withIndexDo: [:each :i |
2289
+ variables at: i put: each].
2290
+ anInspector
2291
+ setLabel: self printString;
2292
+ setVariables: variables
2293
+ ! !
2294
+
2295
+ !String methodsFor: '*IDE'!
2296
+
2297
+ inspectOn: anInspector
2298
+ | label |
2299
+ super inspectOn: anInspector.
2300
+ self printString size > 30
2301
+ ifTrue: [label := (self printString copyFrom: 1 to: 30), '...''']
2302
+ ifFalse: [label := self printString].
2303
+ anInspector setLabel: label
2304
+ ! !
2305
+
2306
+ !MethodContext methodsFor: '*IDE'!
2307
+
2308
+ inspectOn: anInspector
2309
+ | variables |
2310
+ variables := Dictionary new.
2311
+ variables at: '#self' put: self.
2312
+ variables at: '#home' put: self home.
2313
+ variables at: '#receiver' put: self receiver.
2314
+ variables at: '#selector' put: self selector.
2315
+ variables at: '#temps' put: self temps.
2316
+ self class instanceVariableNames do: [:each |
2317
+ variables at: each put: (self instVarAt: each)].
2318
+ anInspector
2319
+ setLabel: self printString;
2320
+ setVariables: variables
2321
+ ! !
2322
+
2323
+ !HashedCollection methodsFor: '*IDE'!
2324
+
2325
+ inspectOn: anInspector
2326
+ | variables |
2327
+ variables := Dictionary new.
2328
+ variables at: '#self' put: self.
2329
+ variables at: '#keys' put: self keys.
2330
+ self keysAndValuesDo: [:key :value |
2331
+ variables at: key put: value].
2332
+ anInspector
2333
+ setLabel: self printString;
2334
+ setVariables: variables
2335
+ ! !
2336
+