The Trunk: Help-Squeak-Project-ct.108.mcz

[email protected] Mon, 27 Jul 2026 07:33:34 0000
Newsgroups gmane.comp.lang.smalltalk.squeak.general
Message-ID <[email protected]>
Marcel Taeumel uploaded a new version of Help-Squeak-Project to project The Trunk:
http://source.squeak.org/trunk/Help-Squeak-Project-ct.108.mcz

==================== Summary ====================

Name: Help-Squeak-Project-ct.108
Author: ct
Time: 12 July 2026, 3:39:43.650198 am
UUID: 4bb29cb9-81d6-4526-bf41-0aa476359371
Ancestors: Help-Squeak-Project-ct.107

Adds release notes and examples for Squeak 6.1.
Adds experimental outline tool for navigating through the hierarchical structure of the (long) release notes. Later, we could further refine this tool and possibly integrate it into the help browser UI. :-)
Adds a small tutorial for building text links in Squeak.
Small corrections for trees in the keyboard shortcut reference.
Minor: System recategorizations, moves up an example from SqueakContributionHelp to its superclass.

=============== Diff against Help-Squeak-Project-ct.107 ===============

Item was changed:
  SystemOrganization addCategory: #'Help-Squeak-Project'!
+ SystemOrganization addCategory: #'Help-Squeak-Project-Support'!
+ SystemOrganization addCategory: #'Help-Squeak-Project-Tests'!

Item was added:
+ ----- Method: ClassBasedHelpTopic>>outlineRootsFor:in: (in category '*Help-Squeak-Project-Support-outline') -----
+ outlineRootsFor: aHelpTopic in: aText
+ 	"This is not a stable API!!"
+ 
+ 	^ self helpClass outlineRootsFor: aHelpTopic in: aText!

Item was added:
+ ----- Method: MenuMorph>>checkedMatchString: (in category '*Help-Squeak-Project-accessing') -----
+ checkedMatchString: aString
+ 
+ 	self matchString: aString.
+ 	(self items anySatisfy: [:m | m isEnabled]) ifFalse:
+ 		[RemarkNotification signal: ('matchString matches no items: {1}' format: {aString})].!

Item was added:
+ ----- Method: PluggableListMorph>>checkedFilterTerm: (in category '*Help-Squeak-Project-filtering') -----
+ checkedFilterTerm: aString
+ 
+ 	self filterTerm: aString.
+ 	(self hasFilter and: [self getList notEmpty]) ifFalse:
+ 		[RemarkNotification signal: ('filterTerm matches no items: {1}' format: {aString})].!

Item was added:
+ ----- Method: PluggableTreeMorph>>checkedFilterTerm: (in category '*Help-Squeak-Project-filtering') -----
+ checkedFilterTerm: aString
+ 
+ 	self filterTerm: aString.
+ 	(self hasFilter and: [self items anySatisfy: [:m | m extension visible]]) ifFalse:
+ 		[RemarkNotification signal: ('filterTerm matches no items: {1}' format: {aString})].!

Item was removed:
- ----- Method: SqueakContributionHelp class>>openDockingBarMenuThat:filterItem: (in category 'support') -----
- openDockingBarMenuThat: menuBlock filterItem: filterString
- 	"Example:
- 		SqueakContributionHelp
- 			openDockingBarMenuThat: [:m | m contents = 'Tools']
- 			filterItem: 'Squeak Inbox Talk'
- 	Don't delete, this has indeed senders in some TextURL attributes within the pages of this help.
- 	"
- 
- 	| dockingBar menu |
- 	dockingBar := (self currentWorld mainDockingBars ifEmpty: [^ self]) first.
- 	menu := (dockingBar submorphs select: #isMenuItemMorph) detect: menuBlock ifNone: [^ self].
- 	dockingBar selectItem: menu event: self currentEvent.
- 	menu subMenu setProperty: #matchString toValue: filterString.
- 	menu subMenu displayFiltered: self currentEvent.
- 	^ nil "do not answer a Behavior here, which would trigger another browser when sending this message from a TextURL"!

Item was added:
+ Model subclass: #SqueakHelpOutlineTool
+ 	instanceVariableNames: 'helpBrowser outlineRoots lastTopicContents selectedOutlineNode'
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'Help-Squeak-Project-Support'!
+ 
+ !SqueakHelpOutlineTool commentStamp: 'ct 7/9/2026 22:36' prior: 0!
+ Experimental feature for navigating release notes. Later, we might finalize the design and integrate this into the help browser. :-)!

Item was added:
+ ----- Method: SqueakHelpOutlineTool class>>for: (in category 'instance creation') -----
+ for: aHelpBrowser
+ 
+ 	^ self new
+ 		helpBrowser: aHelpBrowser;
+ 		yourself!

Item was added:
+ ----- Method: SqueakHelpOutlineTool class>>openFor: (in category 'opening') -----
+ openFor: aHelpBrowser
+ 
+ 	^ (self for: aHelpBrowser) open!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>buildOutlineWith: (in category 'toolbuilder') -----
+ buildOutlineWith: builder
+ 
+ 	^ builder pluggableTreeSpec new
+ 		model: self;
+ 		name: #outline;
+ 		nodeClass: SqueakHelpTopicOutlineNodeWrapper;
+ 		roots: #outlineRoots;
+ 		getSelected: #selectedOutlineNode;
+ 		setSelected: #selectOutlineNode:;
+ 		getSelectedPath: #selectedOutlinePath;
+ 		filterMode: #all;
+ 		yourself!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>buildWith: (in category 'toolbuilder') -----
+ buildWith: builder
+ 
+ 	| windowSpec |
+ 	windowSpec := self buildWindowWith: builder.
+ 	windowSpec children add:
+ 		((self buildOutlineWith: builder)
+ 			frame: LayoutFrame fullFrame;
+ 			yourself).
+ 	^ builder build: windowSpec!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>editedTopicContents (in category 'accessing') -----
+ editedTopicContents
+ 
+ 	^ self helpTextWidget ifNotNil: [:m | m text]!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>editedTopicContentsSelection (in category 'accessing') -----
+ editedTopicContentsSelection
+ 
+ 	^ self helpTextWidget ifNotNil: [:m | m selectionInterval]!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>helpBrowser (in category 'accessing') -----
+ helpBrowser
+ 
+ 	^ helpBrowser!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>helpBrowser: (in category 'accessing') -----
+ helpBrowser: aHelpBrowser
+ 
+ 	helpBrowser := aHelpBrowser.!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>helpTextWidget (in category 'accessing') -----
+ helpTextWidget
+ 
+ 	^ self helpBrowser anyTextPaneWithSelector: #topicContents!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>initialExtent (in category 'toolbuilder') -----
+ initialExtent
+ 
+ 	^ 300 @ 300!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>labelString (in category 'toolbuilder') -----
+ labelString
+ 
+ 	^ 'Help Outline' translated!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>open (in category 'toolbuilder') -----
+ open
+ 
+ 	^ ToolBuilder open: self!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>outlineRoots (in category 'accessing') -----
+ outlineRoots
+ 
+ 	| parentTopic topic |
+ 	outlineRoots ifNotNil: [^ outlineRoots].
+ 	
+ 	parentTopic := self helpBrowser currentParentTopic.
+ 	topic := self helpBrowser currentTopic.
+ 	(parentTopic isNil or: [topic isNil]) ifTrue: [^ outlineRoots := #()].
+ 	(parentTopic respondsTo: #outlineRootsFor:in:) ifFalse: [^ outlineRoots := #()].
+ 	^ outlineRoots := parentTopic
+ 		outlineRootsFor: topic
+ 		in: self editedTopicContents!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>selectOutlineNode: (in category 'accessing') -----
+ selectOutlineNode: aHelpTopicOutlineNode
+ 
+ 	selectedOutlineNode := aHelpTopicOutlineNode.
+ 	aHelpTopicOutlineNode ifNil: [^ self].
+ 	
+ 	((self currentHand world morphsAt: self currentHand position) anySatisfy: [:m | (m isKindOf: PluggableTreeMorph) and: [m getRootsSelector = #outlineRoots]]) ifTrue: [
+ 		| index |
+ 		index := aHelpTopicOutlineNode startIndexIn: self editedTopicContents.
+ 		self helpTextWidget
+ 			setSelection: (index to: index - 1);
+ 			in: [:m |
+ 				"Not simply #scrollToShow:/#scrollSelectionIntoView: but position the selected line at the top of the view. This is easier to spot when going upward/downward in the tree."
+ 				m vScrollBar setValue: (m textMorph paragraph characterBlockForIndex: index) top].
+ 		"We could also pass keyboard focus to the text widget ... but this feels unfamiliar."
+ 		"self currentEvent isMouse ifTrue:
+ 			[self helpBrowser future changed: #inputRequested with: #topicContents]"].
+ 	
+ 	self changed: #selectedOutlineNode.!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>selectedOutlineNode (in category 'accessing') -----
+ selectedOutlineNode
+ 
+ 	^ SqueakHelpTopicOutlineNode
+ 		findSelectedNodeFrom: self outlineRoots
+ 		in: (self editedTopicContents ifNil: [^ nil])
+ 		at: self editedTopicContentsSelection start!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>selectedOutlinePath (in category 'accessing') -----
+ selectedOutlinePath
+ 
+ 	^ self selectedOutlineNode ifNil: [#()] ifNotNil: [:node | node path]!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>step (in category 'updating') -----
+ step
+ 
+ 	| currentTopicContents newSelection |
+ 	currentTopicContents := self editedTopicContents.
+ 	lastTopicContents = currentTopicContents ifFalse:
+ 		[outlineRoots := nil.
+ 		self changed: #outlineRoots.
+ 		self changed: #selectedOutlineNode.
+ 		self changed: #selectedOutlinePath.
+ 		lastTopicContents := currentTopicContents copy].
+ 	
+ 	newSelection := self selectedOutlineNode.
+ 	newSelection ~= selectedOutlineNode ifFalse: [^ self].
+ 	
+ 	selectedOutlineNode := newSelection.
+ 	self changed: #selectedOutlineNode.!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>stepTimeIn: (in category 'updating') -----
+ stepTimeIn: window
+ 
+ 	^ 20!

Item was added:
+ ----- Method: SqueakHelpOutlineTool>>wantsSteps (in category 'updating') -----
+ wantsSteps
+ 
+ 	^ true!

Item was changed:
  TextAnchor subclass: #SqueakHelpTextImage
  	instanceVariableNames: ''
  	classVariableNames: ''
  	poolDictionaries: ''
+ 	category: 'Help-Squeak-Project-Support'!
- 	category: 'Help-Squeak-Project'!

Item was added:
+ Object subclass: #SqueakHelpTopicOutlineNode
+ 	instanceVariableNames: 'helpTopic sourceText lineIndex label provider parent nextSibling children'
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'Help-Squeak-Project-Support'!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode class>>findSelectedNodeFrom:in:at: (in category 'support') -----
+ findSelectedNodeFrom: rootNodes in: sourceText at: textIndex
+ 
+ 	| nodes parent |
+ 	nodes := rootNodes.
+ 	parent := nil.
+ 	[nodes
+ 		findBinary: [:node | textIndex - (node startIndexIn: sourceText)]
+ 		do: [:node | ^ node]
+ 		ifNone: [:left :right |
+ 			left ifNil: [^ parent].
+ 			nodes := (parent := left) children]]
+ 				repeat.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode class>>for:from:source:lineIndex:label: (in category 'instance creation') -----
+ for: aHelpTopic from: provider source: sourceText lineIndex: anInteger label: aText
+ 
+ 	^ self new
+ 		helpTopic: aHelpTopic;
+ 		provider: provider;
+ 		sourceText: sourceText;
+ 		lineIndex: anInteger;
+ 		label: aText;
+ 		yourself!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>adoptToParent: (in category 'building') -----
+ adoptToParent: aHelpTopicOutlineNode
+ 
+ 	self parent: aHelpTopicOutlineNode.
+ 	self sourceText: self parent sourceText.
+ 	self lineIndex: self lineIndex + self parent lineIndex - 1.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>buildChildren (in category 'building') -----
+ buildChildren
+ 
+ 	^ children := (self provider
+ 		outlineChildrenFor: self helpTopic
+ 		in: self text
+ 		level: self level + 1)
+ 			do: [:node | node adoptToParent: self];
+ 			yourself!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>children (in category 'accessing') -----
+ children
+ 
+ 	^ children ifNil: [self buildChildren]!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>helpTopic (in category 'accessing') -----
+ helpTopic
+ 
+ 	^ helpTopic!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>helpTopic: (in category 'accessing') -----
+ helpTopic: aHelpTopic
+ 
+ 	helpTopic := aHelpTopic.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>label (in category 'accessing') -----
+ label
+ 
+ 	^ label!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>label: (in category 'accessing') -----
+ label: aText
+ 
+ 	label := aText.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>level (in category 'accessing') -----
+ level
+ 
+ 	^ self parent
+ 		ifNil: [1]
+ 		ifNotNil: [:node | node level + 1]!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>lineIndex (in category 'accessing') -----
+ lineIndex
+ 
+ 	^ lineIndex!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>lineIndex: (in category 'accessing') -----
+ lineIndex: anInteger
+ 
+ 	lineIndex := anInteger.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>nextSIbling: (in category 'accessing') -----
+ nextSIbling: aHelpTopicOutlineNode
+ 
+ 	nextSibling := aHelpTopicOutlineNode.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>nextSibling (in category 'accessing') -----
+ nextSibling
+ 
+ 	^ nextSibling!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>nextSibling: (in category 'accessing') -----
+ nextSibling: aHelpTopicOutlineNode
+ 
+ 	nextSibling := aHelpTopicOutlineNode.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>parent (in category 'accessing') -----
+ parent
+ 
+ 	^ parent!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>parent: (in category 'accessing') -----
+ parent: aHelpTopicOutlineNode
+ 
+ 	parent := aHelpTopicOutlineNode.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>path (in category 'accessing') -----
+ path
+ 
+ 	^ (self parent ifNil: [#()] ifNotNil: #path) copyWith: self!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>printOn: (in category 'printing') -----
+ printOn: aStream
+ 
+ 	super printOn: aStream.
+ 	aStream
+ 		nextPut: $(;
+ 		nextPutAll: self label;
+ 		nextPut: $).!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>provider (in category 'accessing') -----
+ provider
+ 
+ 	^ provider!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>provider: (in category 'accessing') -----
+ provider: anObject
+ 
+ 	provider := anObject.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>sourceText (in category 'accessing') -----
+ sourceText
+ 
+ 	^ sourceText!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>sourceText: (in category 'accessing') -----
+ sourceText: aText
+ 
+ 	sourceText := aText.!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>startIndex (in category 'accessing') -----
+ startIndex
+ 
+ 	^ self startIndexIn: self sourceText!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>startIndexIn: (in category 'accessing') -----
+ startIndexIn: aText
+ 
+ 	^ aText indexCorrespondingToLine: self lineIndex character: 1!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNode>>text (in category 'accessing') -----
+ text
+ 
+ 	^ self sourceText
+ 		copyFrom: self startIndex
+ 		to:
+ 			(self nextSibling
+ 				ifNotNil: [:node | (node startIndexIn: self sourceText) - 1]
+ 				ifNil: [self sourceText size])!

Item was added:
+ PluggableListItemWrapper subclass: #SqueakHelpTopicOutlineNodeWrapper
+ 	instanceVariableNames: 'contents'
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'Help-Squeak-Project-Support'!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNodeWrapper>>asString (in category 'accessing') -----
+ asString
+ 
+ 	^ self name!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNodeWrapper>>balloonText (in category 'accessing') -----
+ balloonText
+ 
+ 	^ (self item text truncateWithEllipsisTo: 120) withBlanksTrimmed!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNodeWrapper>>contents (in category 'accessing') -----
+ contents
+ 
+ 	^ contents ifNil: [contents := self item buildChildren collect: [:node |
+ 		self species with: node model: self model]]!

Item was added:
+ ----- Method: SqueakHelpTopicOutlineNodeWrapper>>name (in category 'accessing') -----
+ name
+ 
+ 	^ self item label asString!

Item was changed:
  TestCase subclass: #SqueakMessageCategoriesHelpTest
  	instanceVariableNames: ''
  	classVariableNames: ''
  	poolDictionaries: ''
+ 	category: 'Help-Squeak-Project-Tests'!
- 	category: 'Help-Squeak-Project'!

Item was added:
+ ----- Method: SqueakProjectHelp class>>openDockingBarMenuThat:filterItem: (in category 'support') -----
+ openDockingBarMenuThat: menuBlock filterItem: filterString
+ 	"Example:
+ 		SqueakContributionHelp
+ 			openDockingBarMenuThat: [:m | m contents = 'Tools']
+ 			filterItem: 'Squeak Inbox Talk'
+ 	Don't delete, this has indeed senders in some TextURL attributes within the pages of this help.
+ 	"
+ 
+ 	| dockingBar menu |
+ 	dockingBar := (self currentWorld mainDockingBars ifEmpty: [^ self]) first.
+ 	menu := (dockingBar submorphs select: #isMenuItemMorph) detect: menuBlock ifNone: [^ self].
+ 	dockingBar selectItem: menu event: self currentEvent.
+ 	menu subMenu checkedMatchString: filterString.
+ 	menu subMenu displayFiltered: self currentEvent.
+ 	^ nil "do not answer a Behavior here, which would trigger another browser when sending this message from a TextURL"!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>browseAllContributors (in category 'examples') -----
+ browseAllContributors
+ 
+ 	| t1 |
+ 	t1 := SystemReporter new.
+ 	t1 selectNoCategories
+ 		categoryAt: (t1 categoryList indexOf: 'Contributors')
+ 		put: true.
+ 	^ ToolBuilder open: t1!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>browseGames (in category 'examples - v61') -----
+ browseGames
+ 
+ 	^ (Project current world activateObjectsTool; findA: ObjectsTool)
+ 		doCategoryButtonAction: 'Games';
+ 		yourself!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>browseSharedProtocolOfAll: (in category 'examples - support') -----
+ browseSharedProtocolOfAll: classes
+ 
+ 	| selectors |
+ 	selectors := (classes collect: #selectors) fold: #intersection:.
+ 	^ self systemNavigation
+ 		browseMessageList: (selectors gather: [:sel | classes collect: [:class | (class lookupSelector: sel) asCodeReference]])
+ 		name: ('Common protocol of {1}' format: {classes asCommaStringAnd})!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>colorizeCenteredText:withFont:withFillStyle: (in category 'support') -----
+ colorizeCenteredText: aText withFont: aFont withFillStyle: fillStyleFactory
+ 	"
+ 	SqueakReleaseNotes colorizeCenteredText:
+ 		(Clipboard clipboardText copy removeAttributesThat: [:ea | ea isKindOf: TextColor])
+ 		withFont: TextStyle defaultFont
+ 		withFillStyle: [:extent |
+ 			(GradientFillStyle colors: {Color blue. Color magenta})
+ 				origin: -50 @ -50;
+ 				direction: (Point r: extent r * 1.2 degrees: (200 @ 100 rotateBy: (200 @ 100) theta - extent theta about: 0 @ 0) degrees);
+ 				yourself]
+ 	"
+ 
+ 	^ Text new: aText size streamContents: [:stream |
+ 		| lineWidths lines textHeight textWidth form |
+ 		lines := aText lines.
+ 		textHeight := aFont height * lines size.
+ 		lineWidths := lines collect: [:line | aFont widthOfStringOrText: line].
+ 		textWidth := lineWidths max.
+ 		form := Morph new
+ 			extent: textWidth @ textHeight;
+ 			fillStyle: (fillStyleFactory cull: textWidth @ textHeight);
+ 			imageForm.
+ 		lines withIndexDo: [:line :lineIndex |
+ 			| lineWidth y |
+ 			y := lineIndex + 0.5 / lines size.
+ 			lineWidth := lineWidths at: lineIndex.
+ 			1 to: line size do: [:charIndex |
+ 				| charText charWidth x |
+ 				charText := line copyFrom: charIndex to: charIndex.
+ 				charWidth := aFont widthOfStringOrText: charText.
+ 				x := (aFont widthOfStringOrText: (line first: charIndex)) + (textWidth - lineWidth / 2).
+ 				"stream withAttribute: (TextColor color: (form colorAt: x rounded @ y rounded)) do:
+ 					[stream nextPutAll: charText]"
+ 				stream nextPutAll: (charText addAttribute: (TextColor color: (form colorAt: x rounded @ y rounded)); yourself)].
+ 			lineIndex < lines size ifTrue:
+ 				[stream cr]]]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>combineOutlineMatchers: (in category 'outline') -----
+ combineOutlineMatchers: matchers
+ 
+ 	^ [:line |
+ 		matchers
+ 			inject: line
+ 			into: [:label :matcher | label ifNotNil: [matcher value: label]]]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>doABarrelRoll (in category 'examples - v61') -----
+ doABarrelRoll
+ 
+ 	| window duration start p |
+ 	window := self findHelpBrowser ifNil: [^ nil].
+ 	duration := 2 seconds.
+ 	start := DateAndTime now.
+ 	[(p := DateAndTime now - start / duration) <= 1] whileTrue:
+ 		[window rotationDegrees: 360 * p.
+ 		Project current world doOneCycleNow].
+ 	window removeFlexShell.
+ 	^ window!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleBrowseSourcesFile (in category 'examples - v61') -----
+ exampleBrowseSourcesFile
+ 
+ 	| fileList |
+ 	fileList := (FileList openOn: Smalltalk locateSourcesEntry containingDirectory) model.
+ 	fileList fileListIndex: (fileList fileList findFirst: [:ea | ea endsWith: Smalltalk sourcesFileName]).
+ 	^ fileList!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleBrowseSourcesFileChanges (in category 'examples - v61') -----
+ exampleBrowseSourcesFileChanges
+ 
+ 	| fileList |
+ 	fileList := self exampleBrowseSourcesFile.
+ 	fileList containingWindow ifNotNil: [:w |
+ 		w isMorph ifTrue: [
+ 			(w findDeepSubmorphThat: [:m | m isButton and: [m label = 'changes' translated]] ifAbsent: [nil]) ifNotNil: [:m |
+ 				m color: Color red]]].
+ 	^ fileList!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleBrowseSourcesFileText (in category 'examples - v61') -----
+ exampleBrowseSourcesFileText
+ 
+ 	| fileList |
+ 	fileList := self exampleBrowseSourcesFile.
+ 	fileList changed: #inputRequested with: #contents.
+ 	^ fileList!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleDebuggerByteCodes (in category 'examples - v61') -----
+ exampleDebuggerByteCodes
+ 
+ 	| process debugger |
+ 	process := Process forBlock:
+ 		[2 / 3].
+ 	debugger := process debug.
+ 	debugger stepInto.
+ 	self inform: 'Debugger will now be turned into byteCodes mode.'.
+ 	debugger toggleShowingByteCodes.
+ 	debugger restart.
+ 	^ debugger!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleDebuggerReturnEnteredValue (in category 'examples - v61') -----
+ exampleDebuggerReturnEnteredValue
+ 	"Example taken from SqueakTipOfTheDay (https://github.com/LinqLover/Squeak-TipOfTheDay)."
+ 
+ 	^ (Process forBlock:
+ 		[| collection result |
+ 		self flag: 'Let''s fake that "collection at: 4" would return 100!! To do so, step into #at:ifAbsent:. Then, right-click into the context stack menu, press "return entered value", and enter 100 (or even 10 squared).'.
+ 		collection := {1. 2. 3} asOrderedCollection.
+ 		result := collection at: 4 ifAbsent: [0].
+ 		result = 100
+ 			ifFalse: [self inform: 'Not 100. Total disaster. Very sad!!']
+ 			ifTrue: [self inform: 'You did it!!']])
+ 			debugWithTitle: 'Example debugger' full: true!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleDebuggerRunToHereBlock (in category 'examples - v61') -----
+ exampleDebuggerRunToHereBlock
+ 
+ 	Processor debugWithTitle: 'Debugger' full: true.
+ 	self inform: 'Do this: Select ''borderColor:'', right-click, and press ''run to here''!!'.
+ 	World allMorphs
+ 		detect: [:m | m knownName = #codePane]
+ 		ifFound: [:m | m borderColor: Color red; borderWidth: 5 px].!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleDebuggerSelectHome (in category 'examples - v61') -----
+ exampleDebuggerSelectHome
+ 
+ 	#(1 2 3) sorted:
+ 	[:a |
+ 		Processor debugWithTitle: 'Debugger' full: true.
+ 		self inform: 'Now, yellow-click on the stack list above and press "select home"!!'.
+ 		a] ascending.!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleDebuggerSendUntil (in category 'examples - v61') -----
+ exampleDebuggerSendUntil
+ 
+ 	| process debugger menu |
+ 	process := Process forBlock: [WatchMorph new fullBounds].
+ 	debugger := process debug.
+ 	debugger stepOver; stepInto.
+ 	debugger instVarNamed: 'untilExpression' put: 'fullBounds notNil'.
+ 	debugger codeTextMorph yellowButtonActivity: false.
+ 	menu := self currentWorld findA: MenuMorph.
+ 	menu checkedMatchString: 'send until'.
+ 	menu position: debugger codeTextMorph position + 100 px.
+ 	^ debugger!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleFileContentsBrowser (in category 'examples - v61') -----
+ exampleFileContentsBrowser
+ 
+ 	^ (Smalltalk locateSourcesEntry ifNil: [^ FileContentsBrowser])
+ 		readStreamDo: [:f | FileContentsBrowser browseStream: f]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleMVCProjectScreenMenu (in category 'examples - v61') -----
+ exampleMVCProjectScreenMenu
+ 
+ 	^ MVCProject new
+ 		addDeferredUIMessage: [Project current world screenController projectScreenMenu invokeOn: Project current world screenController];
+ 		enter!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleMonticelloConfiguration (in category 'examples - v61') -----
+ exampleMonticelloConfiguration
+ 
+ 	| inspector |
+ 	inspector := MCFileRepositoryInspector repository: MCRepository trunk workingCopy: nil.
+ 	inspector packageSelection: (inspector packageList indexOf: 'update').
+ 	inspector versionSelection: 1.
+ 	^ inspector show!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleMonticelloDiff (in category 'examples - v61') -----
+ exampleMonticelloDiff
+ 
+ 	^ self openMonticelloDiffFrom: 'Monticello-mt.780' to: MCRepository workingCopy ancestors first name!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleMonticelloVersion (in category 'examples - v61') -----
+ exampleMonticelloVersion
+ 
+ 	^ self openMonticelloVersion: MCRepository workingCopy ancestors first name!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleProgressThemes (in category 'examples - v61') -----
+ exampleProgressThemes
+ 
+ 	| themes previousTheme |
+ 	themes := (UserInterfaceTheme allThemes asArray sort: #name ascending) select: #isGenuine.
+ 	themes ifEmpty: [^ SystemProgressMorph example].
+ 	previousTheme := UserInterfaceTheme current.
+ 	[themes
+ 		do: [:theme |
+ 			theme applyScaled.
+ 			SystemProgressMorph uniqueInstance comeToFront flag: #workaround.]
+ 		displayingProgress: 'Applying themes']
+ 			ensure: [previousTheme apply].
+ 	^ nil!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleSearchBarPrintIt (in category 'examples - v61') -----
+ exampleSearchBarPrintIt
+ 
+ 	| t |
+ 	t := World findDeepSubmorphThat: [:m | m model isKindOf: SearchBar] ifAbsent: [^SearchBar].
+ 	self currentHand newKeyboardFocus: t.
+ 	t setText: '#[1 2 3]'; printIt.
+ 	^ t!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleTestRunnerTimeout (in category 'examples - v61') -----
+ exampleTestRunnerTimeout
+ 
+ 	| environment testClass runner |
+ 	environment := Object newEnvironment
+ 		import: Smalltalk environment;
+ 		yourself.
+ 	testClass := environment beCurrentDuring:
+ 		[TestCase subclass: #SUnitTimeoutTests
+ 			instanceVariableNames: ''
+ 			classVariableNames: ''
+ 			poolDictionaries: ''
+ 			category: SUnitTest category].
+ 	testClass
+ 		compile: 'testNoTimeout
+ 	<timeout: 2 "second">
+ 
+ 	1 seconds wait.'
+ 		classified: 'tests'
+ 		withStamp: 'ct 7/6/2026 00:55'
+ 		notifying: nil;
+ 		compile: 'testTimeout
+ 	<timeout: 1 "second">
+ 
+ 	2 seconds wait.'
+ 		classified: 'tests'
+ 		withStamp: 'ct 7/6/2026 00:55'
+ 		notifying: nil.
+ 	
+ 	runner := TestRunner new.
+ 	runner environment: testClass environment.
+ 	runner update; reset.
+ 	runner categoryAt: (runner categoryList indexOf: testClass category) put: true.
+ 	^ ToolBuilder open: runner!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>exampleTreeBrowserMultipleInheritanceWithTraits (in category 'examples - v61') -----
+ exampleTreeBrowserMultipleInheritanceWithTraits
+ 
+ 	Trait named: #ExampleTrait1
+ 		uses: #()
+ 		category: 'Autogenerated'.
+ 	Trait named: #ExampleTrait2
+ 		uses: #()
+ 		category: 'Autogenerated'.
+ 	Trait named: #ExampleTrait3
+ 		uses: (Smalltalk at: #ExampleTrait2)
+ 		category: 'Autogenerated'.
+ 	Object subclass: #ExampleClass1
+ 		uses: (Smalltalk at: #ExampleTrait1) + (Smalltalk at: #ExampleTrait3)
+ 		instanceVariableNames: ''
+ 		classVariableNames: ''
+ 		poolDictionaries: ''
+ 		category: 'Autogenerated'.
+ 	"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "
+ 	"ExampleClass1 class
+ 		uses: ExampleTrait1 classTrait + ExampleTrait3 classTrait
+ 		instanceVariableNames: ''!!
+ 	"
+ 	Object subclass: #ExampleClass2
+ 		uses: (Smalltalk at: #ExampleTrait2) + (Smalltalk at: #ExampleTrait3)
+ 		instanceVariableNames: ''
+ 		classVariableNames: ''
+ 		poolDictionaries: ''
+ 		category: 'Autogenerated'.
+ 	"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "
+ 	"ExampleClass2 class
+ 		uses: ExampleTrait2 classTrait + ExampleTrait3 classTrait
+ 		instanceVariableNames: ''!!
+ 	"
+ 	
+ 	^ TreeBrowser fullHierarchyOnClass: (Smalltalk at: #ExampleTrait2)!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesCSSColors (in category 'examples - v61') -----
+ examplesCSSColors
+ 
+ (Color fromString: 'rgb(250,150,10)') openAsMorph.
+ (Color fromString: 'rgba(0,50,200,0.5)') openAsMorph.!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesDictionariesWeakTyping (in category 'examples - v61') -----
+ examplesDictionariesWeakTyping
+ | dict1 dict2 fps n posts renderTimes |
+ dict1 := (1 to: 10) collect: [:i | i asWords -> i squared] as: Dictionary.
+ dict2 := dict1 - 10.
+ dict2 - dict1.
+ 
+ posts :=
+ 	{JsonObject new likes: 12; shares: 7; yourself.
+ 	JsonObject new likes: 4; shares: 3; yourself}.
+ posts average.
+ 
+ n := 2000.
+ renderTimes := {Morph new. WatchMorph new. Tetris new. SystemWindow new} collect: [:ea | ea ->
+ 	(([n timesRepeat: [ea imageForm]]) timeToRunWithoutGC / n)] as: OrderedDictionary.
+ fps := 1.0s2 / renderTimes.!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesHTMLWithCSSColors (in category 'examples - v61') -----
+ examplesHTMLWithCSSColors
+ 
+ '<b>I <font color="rgb(50,150,50)">LOVE</font> SQUEAK</b>' asTextFromHtml edit!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesRegexCharacterClass (in category 'examples - v61') -----
+ examplesRegexCharacterClass
+ 
+ '\p{L}' asRegex matches: 'A' "Letter".
+ '\p{Lu}' asRegex matches: 'A' "Letter, uppercase".
+ "See Unicode class>>#generalCategoryLabels for the entire list"
+ 
+ '(\P{N})+' asRegex matches: 'ABC'.
+ '(\P{N})+' asRegex matches: 'AB3'.!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesRegexHexEscape (in category 'examples - v61') -----
+ examplesRegexHexEscape
+ 
+ '\x41' asRegex matches: 'A'.
+ '\x41' asRegex matches: 'a'.
+ 
+ "Let's go fancy with custom bases"
+ '\x{2r1000001}' asRegex matches: 'A'.
+ '\x{ar65}' asRegex matches: 'A'.
+ 
+ '[\x41-\x45]+' asRegex matches: 'ABC'.!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesRegexNamedCaptureGroup (in category 'examples - v61') -----
+ examplesRegexNamedCaptureGroup
+ | matcher |
+ matcher := '(?<num>\d+)/(?<den>\d+)' asRegex.
+ matcher matches: '1/23'.
+ matcher keyedSubexpression: #num.
+ matcher keyedSubexpression: 'den'.
+ 
+ matcher := '((?''elem''[^,;]+)(?''sep''[,;](?!!$)|$))*' asRegex.
+ matcher matches: '1,hello;:-)'.
+ matcher allKeyedSubexpressions.
+ ((matcher keyedSubexpressions: #elem) with: (matcher keyedSubexpressions: #sep) collect: [:a :b | a , b]) join!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesRegexNonCapturingGroup (in category 'examples - v61') -----
+ examplesRegexNonCapturingGroup
+ 
+ '(?:(a)b)+c' asRegex
+ 	matches: 'abc';
+ 	allSubexpressions "#(#('abc') #('a'))"
+ 						"no 'ab'!!"!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesRegexNullableClosure (in category 'examples - v61') -----
+ examplesRegexNullableClosure
+ 
+ 'a bb nope aaa' allRegexMatches: '\<(a|b*)?\>'!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesRegexUnicodeEscape (in category 'examples - v61') -----
+ examplesRegexUnicodeEscape
+ 
+ '\u0041' asRegex matches: 'A'.
+ '\u0041' asRegex matches: 'a'.
+ 
+ "Let's go fancy with custom bases"
+ '\u{1f388}' asRegex matches: (String value: 16r1f388).
+ '\u{3drymo}' asRegex matches: (String value: 16r1f388).
+ 
+ '[\u{0041}-\u{0045}]+' asRegex matches: 'ABC'.!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>examplesSendingPvtToSuper (in category 'examples - v61') -----
+ examplesSendingPvtToSuper
+ 
+ Compiler evaluate: 'super pvtAt: 3' for: (ShortPointArray with: 10@20 with: 30@40)!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>findHelpBrowser (in category 'examples - support') -----
+ findHelpBrowser
+ 
+ 	^ ((SystemWindow windowsIn: Project current world)
+ 		select: [:ea | ea model isKindOf: HelpBrowser])
+ 		detect: [:ea |
+ 			ea model currentParentTopic isClassBasedHelpTopic
+ 				and: [ea model currentParentTopic helpClass = SqueakReleaseNotes]]
+ 		ifNone: [:ea | (ea ifEmpty: [^ nil]) first]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>grabTransferMorphFor:type:from: (in category 'examples - v61') -----
+ grabTransferMorphFor: anObject type: type from: source
+ 
+ 	^ self currentHand grabMorph:
+ 		((TransferMorph
+ 			withPassenger: anObject
+ 			from: source)
+ 				dragTransferType: type;
+ 				yourself)!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>makeOutlineEmphasisMatcher: (in category 'outline') -----
+ makeOutlineEmphasisMatcher: attributes
+ 
+ 	^ self makeOutlineMatcher: [:line |
+ 		line runs allSatisfy: [:attrs | attrs includesAllOf: attributes]]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>makeOutlineMatcher: (in category 'outline') -----
+ makeOutlineMatcher: predicateBlock
+ 
+ 	^ [:line |
+ 		(predicateBlock value: line) ifTrue:
+ 			[line]]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>makeOutlineRegexMatcher: (in category 'outline') -----
+ makeOutlineRegexMatcher: patternString
+ 
+ 	| regex |
+ 	regex := patternString asRegex.
+ 	^ [:line |
+ 		(regex matches: line) ifTrue:
+ 			[regex subexpression: 2]]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>openBrowser:filterMessages: (in category 'examples - support') -----
+ openBrowser: browser filterMessages: filterTerm
+ 
+ 	browser dependents
+ 		detect: [:ea | ea knownName = #messageList]
+ 		ifFound: [:m | m checkedFilterTerm: filterTerm].
+ 	^ browser!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>openMonticelloDiffFrom:to: (in category 'examples - support') -----
+ openMonticelloDiffFrom: baseVersionName to: targetVersionName
+ 
+ 	| base target |
+ 	PreferenceWizardMorph new hasInternetConnection ifFalse:
+ 		[^ self inform: ('See diff from {1} and {2} on {3}' format: {baseVersionName. targetVersionName. MCRepository trunk description})].
+ 	base := MCRepository trunk versionNamed: baseVersionName , '.mcz'.
+ 	target := MCRepository trunk versionNamed: targetVersionName , '.mcz'.
+ 	^ MCVersionHistoryBrowser new
+ 		viewChanges: target info
+ 		snapshot: target snapshot
+ 		relativeTo: base info
+ 		snapshot: base snapshot!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>openMonticelloVersion: (in category 'examples - support') -----
+ openMonticelloVersion: versionName
+ 
+ 	PreferenceWizardMorph new hasInternetConnection ifFalse:
+ 		[^ self inform: ('See: {1}' format: {MCRepository trunk description , '/' , versionName , '.diff'})].
+ 	^ (MCRepository trunk versionNamed: versionName , '.mcz') open!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>openSystemReporterOnVMParameters (in category 'examples - support') -----
+ openSystemReporterOnVMParameters
+ 
+ 	| reporter |
+ 	reporter := SystemReporter new.
+ 	reporter
+ 		selectNoCategories;
+ 		categoryAt: (reporter categoryList indexOf: 'VM Parameters') put: true.
+ 	^ ToolBuilder open: reporter!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>openWorkspaceExample:title: (in category 'examples - support') -----
+ openWorkspaceExample: selector title: aString
+ 
+ 	^ Project uiManager
+ 		edit: (((self class sourceCodeAt: selector) lines allButFirst: 2) joinSeparatedBy: String cr)
+ 		label: aString
+ 		shouldStyle: true!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>openWorkspaceExample:title:shouldStyle: (in category 'examples - support') -----
+ openWorkspaceExample: selector title: aString shouldStyle: aBoolean
+ 
+ 	^ Project uiManager
+ 		edit: (((self class sourceCodeAt: selector) lines allButFirst: 2) joinSeparatedBy: String cr)
+ 		label: aString
+ 		shouldStyle: aBoolean!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>outlineChildrenFor:in:level: (in category 'outline') -----
+ outlineChildrenFor: aHelpTopic in: aText level: level
+ 
+ 	| matcher children |
+ 	matcher := self outlineMatchers at: level ifAbsent: [^ #()].
+ 	children := Array streamContents: [:stream |
+ 		| previous |
+ 		previous := nil.
+ 		aText lines withIndexDo: [:line :index |
+ 			line ifNotEmpty:
+ 				[(matcher value: line) ifNotNil: [:label |
+ 					| current |
+ 					current := SqueakHelpTopicOutlineNode
+ 						for: aHelpTopic
+ 						from: self
+ 						source: aText
+ 						lineIndex: index
+ 						label: label.
+ 					stream nextPut: current.
+ 					previous ifNotNil: [previous nextSibling: current].
+ 					previous := current]]]].
+ 	^ children ifEmpty:
+ 		[self outlineChildrenFor: aHelpTopic in: aText level: level + 1]!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>outlineMatchers (in category 'outline') -----
+ outlineMatchers
+ 
+ 	^
+ 		{self combineOutlineMatchers:
+ 			{self makeOutlineRegexMatcher: '(?:\*\*\* )?((?:(?!! \*\*\*)(?!!\(up to).)*)(?:(?: \*\*\*)| \(up to \w[-\w]*-(\p{L}+\.\d+|(\w+-)?x+)(\/\w[-\w]*-(\p{L}+\.\d+|(\w+-)?x+))*\)|\:)?$'. "top heading and bold sections (deprecations now also have version names)"
+ 			self makeOutlineEmphasisMatcher: {TextEmphasis bold}.
+ 			self makeOutlineMatcher: [:line | line hasColorAttribute not]}.
+ 		self combineOutlineMatchers:
+ 			{self makeOutlineEmphasisMatcher: {TextEmphasis bold}.
+ 			self makeOutlineRegexMatcher: '~~~ (.*) ~~~'}. "package group"
+ 		self combineOutlineMatchers:
+ 			{self makeOutlineMatcher: [:line | (line attributesAt: 1) includes: TextEmphasis italic].
+ 			self makeOutlineRegexMatcher: '(\w((?!!\(up to|[\.\:]$).)*)( \(up to \w[-\w]*-(\p{L}+\.\d+|(\w+-)?x+)(\/\w[-\w]*-(\p{L}+\.\d+|(\w+-)?x+))*\)|\:)?$' "package (with version names)"}}!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>outlineRootsFor:in: (in category 'outline') -----
+ outlineRootsFor: aHelpTopic in: aText
+ 
+ 	^ self outlineChildrenFor: aHelpTopic in: aText level: 1!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>requireFFI: (in category 'examples - support') -----
+ requireFFI: aBlock
+ 
+ 	(Smalltalk hasClassNamed: #ExternalObject) ifFalse:
+ 		[(Project uiManager confirm: 'Install FFI?' title: 'FFI required') ifFalse: [^ nil].
+ 		Metacello new
+ 			configuration: 'FFI';
+ 			load].
+ 	^ aBlock value!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>requireOSProcess: (in category 'examples - support') -----
+ requireOSProcess: aBlock
+ 
+ 	(Smalltalk hasClassNamed: #OSProcess) ifFalse:
+ 		[(Project uiManager confirm: 'Install OSProcess?' title: 'OSProcess required') ifFalse: [^ nil].
+ 		Installer ss project: 'OSProcess'; install: 'OSProcess'.
+ 		Installer ss project: 'CommandShell'; install: 'CommandShell'.].
+ 	^ aBlock value!

Item was added:
+ ----- Method: SqueakReleaseNotes class>>selectorsUsedInExamples (in category 'support') -----
+ selectorsUsedInExamples
+ 	"Documentation only. This list is likely incomplete but should at least work as a canary for some popular selectors that you might want not to change without checking examples in the text attributes in the pages of this help class."
+ 
+ 	^ {
+ 		SqueakReleaseNotes. SqueakProjectHelp.
+ 		"v60 not documented :("
+ 		"v61"
+ 		#browse. #explore. #exploreWithLabel:. #inspect. #valueSupplyingAnswer:.
+ 		Browser class>>#fullOnClass:. CodeHolder>>#toggleShowingByteCodes. HelpBrowser class>>#openOn:. HelpBrowser>>#showTopicNamed:. Inspector>>#selectFieldNamed:. MessageTrace class>>#openMessageList:name:. MessageTrace>>#addParentMessages:autoSelectString:. Preference>>#open. Preferences class>>#pragmaPreferenceFor:getter:. Process class>>#forBlock:. Process class>>#forContext:priority:. Process>>#debug. Process>>#debugWithTitle:. SystemNavigation>>#browseAllCallsOn:localToPackage:. SystemNavigation>>#browseAllImplementorsOf:. SystemNavigation>>#browseAllImplementorsOfList:. SystemNavigation>>#browseMessageList:name:. #(Definition Comment). SystemNavigation>>#methodHierarchyBrowserForClass:selector:. SystemWindow class>>#windowsIn:. ToolSet class>>#browseClass:category:. ToolSet class>>#br
 owseCommentOf:. ToolSet class>>#browseMessageNames:. ToolSet class>>#browseMethodVersion:. ToolSet class>>#browseVersionsOf:selector:. UIManager>>#edit:label:shouldStyle:.
+ 	}!

Item was changed:
  ----- Method: SqueakReleaseNotes class>>v61 (in category 'pages') -----
(excessive size, no diff calculated)

Item was added:
+ ----- Method: SqueakReleaseNotes class>>viewOutline (in category 'examples - v61') -----
+ viewOutline
+ 
+ 	| outline |
+ 	outline := (SqueakHelpOutlineTool openFor: SqueakReleaseNotes findHelpBrowser model) model.
+ 	([outline changed: #expandNodeRequested with: {nil. outline outlineRoots second}] future: 1 "??") value.
+ 	^ outline!

Item was changed:
  ----- Method: SqueakTutorials class>>pages (in category 'accessing') -----
  pages
+ 	<generated>
+ 	^ #(#introduction #usefulExpressions #textLinks)!
- 	^#(introduction usefulExpressions)!

Item was added:
+ ----- Method: SqueakTutorials class>>textLinks (in category 'pages') -----
+ textLinks
+ 	"This method was automatically generated. Edit it using:"
+ 	"SqueakTutorials edit: #textLinks"
+ 	<generated>
+ 	^(HelpTopic
+ 		title: 'Text Links'
+ 		contents: 
+ 'There are several ways to build text links in Squeak:
+ 
+ Links in editors
+ Select some text in an editor (like this one) and press Cmd+5. Search the upcoming menu for "link" options.
+ For instance, you can create links to the definition of a Class, the hierarchy of a Class, or a CompiledBlock method. Via "URL link...", you can also insert weblinks.
+ A particular feature of URL links is that Squeak supports code:// URLs like these:
+ 
+ code://TextURL
+ code://TextURL class>>#url:
+ code://self inform: ''Hello from Smalltalk!!!!''
+ 
+ Programmatic links
+ You can create the above described types of links programmatically as well:
+ 
+ ''Class'' asText addAttribute: (TextLink new classAndMethod: ''Class Definition''); inspect.
+ ''Class hierarchy'' asText addAttribute: (TextLink new classAndMethod: ''Class Hierarchy''); inspect.
+ ''A method'' asText addAttribute: (TextLink new classAndMethod: ''CompiledBlock method''); inspect.
+ 
+ And for URLs:
+ 
+ ''URL'' asText addAttribute: (TextURL url: ''https://squeak.org''); inspect.
+ 
+ Another type of links are pluggable text attributes, which store an actual block closure instead of a static code string:
+ 
+ | x |
+ x := 42.
+ ''Interactive text'' asText addAttribute: (PluggableTextAttribute evalBlock: [x halt]); inspect.
+ 
+ For programmers, pluggable text attributes are often more convenient as they offer syntax checking and can reference temporary variables and found through senders/implementors. However, they cannot be serialized as HTML or text chunks.!!
+ ]style[(55 16 57 5 105 5 21 5 7 20 41 8 60 7 19 14 1 27 1 43 2 18 78 7 1 6 1 13 11 3 1 15 1 18 3 7 2 17 1 6 1 13 11 3 1 15 1 17 3 7 2 10 1 6 1 13 11 3 1 15 1 22 3 7 1 17 5 1 6 1 13 10 4 1 20 3 7 2 124 1 1 1 1 1 1 1 1 2 1 2 2 18 1 6 1 13 25 10 1 1 1 1 4 1 3 7 1 217 4 4 11 1),b,,i,,LClass Definition;,,LClass Hierarchy;,,LCompiledBlock method;,,Rhttps://squeak.org;,,++,,Rcode://TextURL;I1,I1,Rcode://TextURL class>>#url:;I1,I1,Rcode://self inform: ''Hello from Smalltalk!!!!'';I1,,b,,c125000125nI1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c125000125nI1,I1,c000000125I1,I1,c125000125nI1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c125000125nI1,I1,c000000125I1,I1,c125000125nI1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c1250
 00125nI1,I1,c000000125I1,I1,,c125000125nI1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c125000125nI1,I1,c000000125I1,I1,,cgray;I1,I1,c105105105I1,I1,cgray;I1,I1,c105105105I1,I1,bI1,I1,c125000
 000I1,I1,c125000125nI1,I1,c000000125I1,I1,c000000125I1,I1,c000000125I1,I1,c000125000I1,c105105105I1,I1,c000000125I1,c000125000I1,I1,c000000125I1,I1,,Rcode://Text>>#printHtmlString;,,Rcode://WriteStream>>#nextChunkPutWithStyle:;,!!' readStream nextChunkText)
+ 			key: #textLinks;
+ 			shouldStyle: false;
+ 			yourself!

Item was changed:
  ----- Method: SqueakTutorialsCommandKey class>>commandKeyMappings (in category 'pages') -----
  commandKeyMappings
  	"This method was automatically generated. Edit it using:"
  	"SqueakTutorialsCommandKey edit: #commandKeyMappings"
  	<generated>
  	^(HelpTopic
  		title: 'Command Key Mappings'
  		contents: 
  'This page summarizes different shortcuts that are available in text editors and other parts of the UI. Note that some modifier keys work differently on different platforms. On platforms different than Mac, Cmd translates to Alt. See the related keyboard preferences for more details.
  
  Lower-case command keys
  (use with Cmd key on Mac and Alt key on other platforms)
  a	Select all
  b	Browse it (selection is a class name or cursor is over a class-list or message-list)
  c	Copy selection
  d	Do it (selection is a valid expression)
  e	Exchange selection with prior selection
  f	Find text with a dialog
  g	Find the current selection again
  j	Repeat the last selection replacement
  i	Inspect it
  k	Set font
  l	Cancel text edit
  m	Implementors of it
  n	Senders of it
  o	Spawn current method
  p	Print it (selection is a valid expression)
  q	Query symbol (toggle all possible completion for a given prefix)
  s	Save (i.e. accept)
  t	Finds a Transcript (when cursor is over the desktop)
  u	Toggle alignment
  v	Paste
  w	Select/Delete preceding word (over text);  Close-window (over morphic desktop)
  x	Cut selection
  y	Swap characters
  z	Undo
  
  Note: for Do it, Senders of it, etc., a null selection will be expanded to a word or to the current line in an attempt to do what you want.  Also note that Senders/Implementors of it will find the outermost keyword selector in a large selection, as when you have selected a bracketed expression or an entire line.  Finally note that the same cmd-m and cmd-n (and cmd-v for versions) work in the message pane of most browsers.
  
  Upper-case command keys
  (use with Shift-Cmd, or Ctrl on Mac
  or Shift-Alt on other platforms; sometimes Ctrl works too)
  A	Advance argument
  B	Browse it in this same browser (in System browsers only)
  C	Compare the selected text to the clipboard contents
  D	Debug-It
  E	Method strings containing it
  F	Insert ''ifFalse:''
  G	fileIn from it (a file name)
  H	Move cursor to top/home of text
  I	Inspect via Object Explorer
  J	Again many (apply the previous text command repeatedly until the end of the text)
  K	Set style
  M	Select current type-in
  N	References to it (selection is a class name, or cursor is over a class-list or message-list)
  O	Open single-message browser (in message lists)
  P	Make project link
  S	Pretty-print a method in the current browser
  T	Insert ''ifTrue:''
  U	Convert linefeeds to carriage returns in selection
  V	Paste author''s initials
  W	Selectors containing it (in text); show-world-menu (when issued with cursor over desktop)
  X	Force selection to lowercase
  Y	Force selection to uppercase
  Z	Redo
  
  Tip: Not happy with the default shortcuts? You can customize them by editing the methods initializeCmdKeyShortcuts and initializeShiftCmdKeyShortcuts and updating them as instructed in the method comment!!!!
  
  Other special keys
  Backspace			Backward delete character
  Shift-Backspace	Backward select or delete word
  Del					Forward delete character
  Shift-Del			Forward delete word
  Esc					Pop up the context menu
  Shift+Esc			Pop up the World Menu
  Cmd+Esc			Close the active window
  Ctrl+Esc			Present a list of open windows
  Cmd+\				Send the active window to the back
  Tab					Insert a tab char in a single-line selection or insert a tab at the beginning of each line in a multi-line selection
  Shift-Tab			Remove a tab from the beginning of each line in the selection
  Shift-Cmd-_	(underscore) condense selection into one line
  
  Cursor keys (in editors, lists, and trees)
  left, right,
  up, down			Move cursor left, right, up or down
  Ctrl-left				Move cursor left one word
  Ctrl-right			Move cursor right one word
  Home				Move cursor to begin of line or begin of text
  End				Move cursor to end of line or end of text
  PgUp				Move cursor up one page
  PgDown			Move cursor down one page
  Ctrl-up				Scroll page up
  Ctrl-down			Scroll page down
  
  Note all these keys can be used together with Shift to define or enlarge the selection.
  
  Other Cmd-key combinations
  (not available on all platforms)
  Cmd+Return	Insert new line without indentation
  Cmd+Space	Select the current word as with double clicking
  
  Enclose the selection in a pair of brackets (preference)
  (not available on all platforms)
  (	Enclose selection with parentheses
  )	Remove parentheses from selection
  [	Enclose selection with brackets
  ]	Remove brackets from selection
  {	Enclose selection with curly braces
  }	Remove curly braces from selection
  <	Enclose selection with chevrons
  >	Remove chevrons from selection
  "	Toggle enclosure within double-quotes
  ''	Toggle enclosure within single-quotes
  |	Toggle enclosure within pipes
  
  Legacy enclosure shortcuts (QWERTY layout only -- need to be enabled in the preferences)
  Ctrl-(	Toggle enclosure within parentheses
  Cmd-[	Toggle enclosure within brackets
  Ctrl-{	Toggle enclosure within curly braces
  Ctrl-''''	Toggle enclosure within double-quotes
  Cmd-''''	Toggle enclosure within single-quotes
  
  Note also that you can double-click just inside any of the above delimiters, or at the beginning or end of a line, to select the text enclosed.
  
  Text Emphasis
  (not available on all platforms)
  Cmd-1	type the first method argument
  Cmd-2	type the second method argument
  Cmd-3	type the third method argument
  Cmd-4	type the fourth method argument
  Cmd-5	color, action-on-click, link to class comment, link to method, url, custom attributes (brings up a menu)
  Cmd-6	italic
  Cmd-7	bold
  Cmd-8	struck-out
  Cmd-9	underlined
  Cmd-0	make plain (removes all attributes)
  
  And remember this: nine is fine for underline, obliter-eight it as you see fit, seven has been bold for ever''n, which leaves six as the obvious fix to emphasize your poetics.
  
  Docking Bar
  Ctrl-<n> opens the n-th (where n is between 0 and 9) menu if such exists, otherwise it moves the keyboard focus to the Search Bar. Currently -- and depending on your preferences -- this means:
  Ctrl-0	Activates Search Bar or Scratch Pad
  Ctrl-1	Squeak menu
  Ctrl-2	Projects menu
  Ctrl-3	Tools menu
  Ctrl-4	Apps menu
  Ctrl-5	Do menu (an editable menu of useful expressions)
  Ctrl-6	Extras menu
  Ctrl-7	Windows menu
  Ctrl-8	Help menu	
  Ctrl-9	Changeset menu
  
  Lists, trees, and menus
  up, down			Select previous/next item
  Home, End			Select first/last item
  PgUp, PgDown		Move selection up/down one page
  Letters or digits		Type to filter
  Tab, Shift-Tab		Select next/previous column for filtering (if applicable)
  Backspace			Delete current filter and restore selection
  Enter				Delete filter and keep selection
  Esc					Toggle context menu
  Space				Toggle selection of current item (only in multi-selection lists)
  
+ Trees
- Lists and trees
  up, down		Select previous/next visible node
+ Shift-up,
+ Shift-down		Select previous/next sibling of current node
  left				Collapse current node if expanded, otherwise select parent
  right			Expand current node if collapsed, otherwise select first child
  Shift-right, Shift-
  click a triangle	Expand current node and all its successors recursively
- Shift-up,
- Shift-down		Select previous/next sibling of current node
  Cmd-f			Find node with a dialog (deep tree search)
  Cmd-g			Find node again with previous query
  
  Windows
  Most of these shortcuts require hovering the title bar of the target     window (or another part of it that does not respond to keypresses on its own).
  Cmd-w			Close top window
  Cmd-Esc		Close current window (not available on all platforms)
  Cmd-/			Bring window under hand to front (requires the preferences Windows'' contents are always active and Mouse over for keyboard focus to be enabled)
  Cmd-\			Send top window to back
  
  Global world shortcuts
  Some of these shortcuts work globally, while for others, no window/text editor must be focused.
  b	Open a new system browser
  k	Open a new workspace
  m	Put up the "New Morph" menu
  o	Activate the "Objects Tool"
  r	Redraw the screen
  t	Open a transcript
  z	Undo or redo the last undoable command
  C	Open a change sorter
  F	Toggle the display of flaps
  L	Open a FileList
  M	Show/hide the main docking bar
  O	Open a Monticello repository browser
  P	Open a preference browser
  R	Browse recent submissions
  W	Open a MessageNames tool
  Z	Browse/restore recent changes
  +	Increase scale 
  -	Decrease scale factor
  _	Quit the image immediately without saving
  ]	Save the image
  
  Tip: You can explore and change all global shortcuts in PasteUpMorph>>#defaultDesktopCommandKeyTriplets!!!!!!
+ ]style[(237 28 20 24 56 1171 24 95 881 89 25 5 30 55 2 19 594 43 454 26 33 107 45 10 2 32 396 26 50 11 219 24 12 110 14 33 538 12 166 11 270 23 428 5 438 7 208 32 68 35 5 29 49 22 651 56 47 1),Rcode:// PreferenceBrowser open searchPattern: ''keystrokes involving'';,,b,i,,b,i,,i,Rcode://self systemNavigation browseAllImplementorsOf: #initializeCmdKeyShortcuts;i,i,Rcode://self systemNavigation browseAllImplementorsOf: #initializeShiftCmdKeyShortcuts;i,i,,b,,b,,b,i,,b,Rcode:// (Preferences pragmaPreferenceFor: TextEditor getter: #encloseSelection) openInCategory: ''editing'';b,b,i,,bc085085085,c085085085,Rcode:// (Preferences pragmaPreferenceFor: LegacyShortcutsFilter getter: #legacyShortcutsEnabled) openInCategory: ''editing'';,c085085085,,b,,b,i,,b,,Rcode:// PreferenceBrowser open selecte
 dCategory: ''docking bars'' capitalized;,,b,,b,,b,,i,,Rcode://(Preferences pragmaPreferenceFor: Model getter: #windowActiveOnFirstClick) open;,,Rcode://(Preferences preferenceAt: #mouseOverForKeyboa
 rdFocus) open;,,b,,i,Rcode://PasteUpMorph>>#defaultDesktopCommandKeyTriplets;i,i!!' readStream nextChunkText)
- ]style[(237 28 20 24 56 1171 24 95 881 89 25 5 30 55 2 19 594 43 454 26 33 107 45 10 2 32 396 26 50 11 219 24 12 110 14 33 538 12 166 11 270 23 428 15 438 7 208 32 68 35 5 29 49 22 651 56 47 1),Rcode:// PreferenceBrowser open searchPattern: ''keystrokes involving'';,,b,i,,b,i,,i,Rcode://self systemNavigation browseAllImplementorsOf: #initializeCmdKeyShortcuts;i,i,Rcode://self systemNavigation browseAllImplementorsOf: #initializeShiftCmdKeyShortcuts;i,i,,b,,b,,b,i,,b,Rcode:// (Preferences pragmaPreferenceFor: TextEditor getter: #encloseSelection) openInCategory: ''editing'';b,b,i,,bc085085085,c085085085,Rcode:// (Preferences pragmaPreferenceFor: LegacyShortcutsFilter getter: #legacyShortcutsEnabled) openInCategory: ''editing'';,c085085085,,b,,b,i,,b,,Rcode:// PreferenceBrowser open select
 edCategory: ''docking bars'' capitalized;,,b,,b,,b,,i,,Rcode://(Preferences pragmaPreferenceFor: Model getter: #windowActiveOnFirstClick) open;,,Rcode://(Preferences preferenceAt: #mouseOverForKeybo
 ardFocus) open;,,b,,i,Rcode://PasteUpMorph>>#defaultDesktopCommandKeyTriplets;i,i!!' readStream nextChunkText)
  			key: #commandKeyMappings;
  			shouldStyle: false;
  			yourself!

Squeak-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]