resin 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+