HyperTalk has no abstract super class of Hypertext because hypertext is just a network of hypertext components, and the hypertext applications access them individually. According to the Dexter Reference Model [dexter 1st paper], the basic components of hypertext are atomic component, composite component, and link component. HyperComponent is defined as the super class of hypertext components. HyperAtom, HyperComposite and HyperLink are its concrete subclasses which represent composite component and link component respectively.
HyperApp is the abstract super class for hypertext domain models. Its main function is to coordinate, initialize and delegate functionalities to its different components. HyperApp is a Facade[Ralph's book] object for the following components:
Fig. XX
A HyperApp has a HyperRenderer, a LinkAccessor, and a StreamManager. It uses HyperRenderer to create VisualComponents that represents the HyperComponent in the main window of the application. It uses LinkAccessor to retrieve the destination HyperComponent specified by a HyperLink. Besides, one or more LinkResolvers are also registered as dependents of HyperApp.
The controller converts user actions into instances of WebGUIAction. HyperApp then broadcasts these actions to all its LinkResolvers so that they can resolve a HyperLink for HyperApp. The section on LinkResolver has more details.
Once a new HyperLink is retrieved, HyperApp delegates to LinkAccessor to access the destination HyperComponent. If the access is a retrieval, the LinkAccessor sends the resulting stream of the content and component information of the destination HyperComponent to StreamManager. The StreamManager then determines the next step.
Based on the component information of the HyperComponent, the StreamManager either assigns an external Viewer or the combination of StreamFilter and HyperRenderer to consume it.
HyperRenderer gets the elements in the stream converted by the parser one by one, and then it assigns a RenderPolicy to each of them. The RenderPolicy is responsible for presenting these nodes to the user. It first makes a VisualComponent, such as a ComposedText. Then it puts the VisualComponent and the parse tree node into a VisualLink. When HyperRenderer renders a hypertext composite component (HyperComposite), the HyperComponents it contains are retrieved by sending the message retrieve: to HyperApp. The mechanism is similar to the above except the component is retrieved and saved into a temporary file first. For example, when the HyperRenderer of NetFish renders a WebComponent with type #image, it asks HyperApp to retrieve that image by the message #retrieve:. The content of the image is saved into a temporary file so that the Renderer can load the image into the main window later.
The dependents of HyperApp can be any objects or models that are interested in the user's actions inside HyperApp. For example, WebClient is a concrete subclass of HyperApp. Its dependents include a view, LinkResolvers, and different caches. Any object can be dependent on HyperApp by registering themselves to HyperApp by the message #registerSubscriber:. They also register the LinkResolvers that can retrieve links they are interested in. For example, suppose an English Dictionary model registers itself with a HyperApp. It also registers its LinkResolver, say WordResolver, which can retrieve the word a user has just clicked. When HyperApp broadcasts the word retrieved by WordResolver, the English Dictionary model finds it interesting based on the aspect symbol broadcasted. The English Dictionary model might then pop up the definition of that word.
The section on the design of NetFish contains a detailed example of how a concrete subclass of HyperApp functions.