|
Class: HTMLDocumentPainter
Object
|
+--HTMLDocumentInterpreter
|
+--HTMLDocumentPainter
- Package:
- stx:libhtml
- Category:
- System-Documentation
- Version:
- rev:
1.380
date: 2019/07/22 07:10:28
- user: cg
- file: HTMLDocumentPainter.st directory: libhtml
- module: stx stc-classLibrary: libhtml
- Author:
- Claus Gittinger
This one is responsible to paint a document (a linked list
of HTMLElements) into some drawable.
The major entry points are:
format:for:resolver:style:
to scan the list for applets, widgets
and preformat it.
reformatDocument
to reformat the document after a size change of the
drawable.
displayX:y:width:height:on:
to redraw (part of) the document.
Caveat:
This was written at a time when machines with 4M of main memory were
considered as ''big machines''. So the code tries hard to save memory,
in order to be able to display big documents on such small machines reasonably fast.
This is done by avoiding an in-memory html dom-tree, but instead reparsing the
document for redraws, and repeating the layout computations every time we draw.
Of course, in order to figure out what to draw when positioning (scrolling),
we would have to redo all calculations from the start of the document.
(i.e. parse the whole document for every redraw).
Which would be a stupid idea, making the thing super slow.
Therefore, it saves so called sync-points, which contain the captured state
(x, y position, font, position in document etc.), after every few pages worth
of text. So, to update any random page, it has to search for the last sync-point
before that page, and rerender (parse) from there till the end of the visible page.
This scheme works quite well for simple documents in those small-memory systems,
but it is complicated, error prone, and has problems with more complex documents
(involving style, box models, complex tables etc.).
So now, as we have gigabytes of memory, noone would do it that way.
Meaning:
it ought to be rewritten, to implement a proper dom tree, and the drawing
engine to implement a proper box model.
However:
we are not going into the browser business here and there is no return of
investment if we tried.
The HTMPainter was written for, and should only be used to display simple help texts,
online documentation and html tooltips.
It will also not be enhanced and maintained, except for obvious bugs which
break rendering the above mentioned use cases.
Anyone in need for such a thing should investigate better renderers
(which exist - both written in Smalltalk and as plugins,
using common rendering engines or embedded frameworks like CEF).
[pending bugs:]
these should be fixed, to make the documentation viewing nicer.
- <nobr> must collect text and determine if a break should be done at the beginning
- <pre>...</pre> inserts an extra empty line
- <table> is almost useless
HTMLParser
HTMLDocumentView
contents
-
headerAsString: anArray depht: depth
-
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
headerAsString: anArray depth: depth
-
returns printable header assigned to array
helpers
-
fontFor: aFont onDevice: aDevice
-
-
romanStringFor: aNumber
-
aNumber >= 100 ifTrue:[
usage example(s):
^ 'C' , (self romanStringFor:aNumber - 100)
|
usage example(s):
^ 'L' , (self romanStringFor:aNumber - 50)
|
usage example(s):
^ 'X' , (self romanStringFor:aNumber - 10)
|
usage example(s):
^ 'V' , (self romanStringFor:aNumber - 5)
|
usage example(s):
^ 'I' , (self romanStringFor:aNumber - 1)
|
usage example(s):
HTMLDocumentPainter new romanStringFor:110
HTMLDocumentPainter new romanStringFor:99
HTMLDocumentPainter new romanStringFor:9
HTMLDocumentPainter new romanStringFor:4
HTMLDocumentPainter new romanStringFor:5
|
image specs
-
bullet1
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
usage example(s):
self bullet1 inspect
ImageEditor openOnClass:self andSelector:#bullet1
Icon flushCachedIcons
|
-
bullet2
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
usage example(s):
self bullet2 inspect
ImageEditor openOnClass:self andSelector:#bullet2
Icon flushCachedIcons
|
-
bullet3
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
usage example(s):
self bullet3 inspect
ImageEditor openOnClass:self andSelector:#bullet3
Icon flushCachedIcons
|
-
bullet4
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
usage example(s):
self bullet4 inspect
ImageEditor openOnClass:self andSelector:#bullet4
Icon flushCachedIcons
|
-
bullet5
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
usage example(s):
self bullet5 inspect
ImageEditor openOnClass:self andSelector:#bullet5
Icon flushCachedIcons
|
-
bullet6
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
usage example(s):
self bullet6 inspect
ImageEditor openOnClass:self andSelector:#bullet6
Icon flushCachedIcons
|
-
bullet7
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
-
bullet8
-
This resource specification was automatically generated
by the ImageEditor of ST/X.
usage example(s):
self bullet8 inspect
ImageEditor openOnClass:self andSelector:#bullet8
Icon flushCachedIcons
|
initialization
-
initialize
-
self initialize
instance creation
-
new
-
return an initialized instance
accessing
-
applets
-
return a collection of my applets
-
arrayOfHeaderIndex
-
returns current header index
-
forms
-
return a collection of my forms
-
imageResolver: somethingProvidingImagesGivenURL
-
Modified (format): / 29-06-2018 / 16:35:32 / Claus Gittinger
-
leftMargin
-
-
leftMargin: something
-
-
listOfHeaders
-
returns current list of headers
-
rightMargin
-
-
rightMargin: something
-
-
scriptObject
-
return my scriptObject - if any
-
topMargin
-
-
topMargin: something
-
accessing-private
-
currentBGColor
-
-
currentColIndex
-
-
currentColor
-
-
currentElement
-
-
currentFont
-
-
currentFontAscent
-
-
currentFontAvgHeight
-
-
currentFontHeight
-
-
currentForm
-
-
currentIndentOffset
-
-
currentLeftIndent
-
-
currentRightIndent
-
-
currentRowIndex
-
-
currentTable
-
-
currentUnderlineColor
-
-
document: aDocument
-
-
hBegin
-
-
haveSpace
-
-
inBLOCKQUOTE
-
-
inCenter
-
-
inDL
-
-
inKbd
-
-
inNoBreak
-
-
inOL
-
-
inPre
-
-
inRightAlign
-
-
inStrikeout
-
-
inSup
-
-
inUnderline
-
-
needSpace
-
-
previousIsEmpty
-
-
styleStack
-
-
ulLevel
-
-
xPosition
-
-
yNextLine
-
-
yPosition
-
-
yText
-
applets
-
createAppletFor: element
-
create the applet
-
defineAppletParameterFor: element
-
add it to its environment information
-
destroyApplet: appletElement
-
-
setupAppletElement: element
-
already present.
checking
-
checkInitialStateAtEndOfDocument
-
check for correct closing TAGS.
Although, most HTML viewers can handle this case, its usually an
indication of some error and often leads to badly formatted documents
-
printCheckInfoMessage: msg
-
contents
-
contentsAddHeader: text
-
assign text to header and store in list of headers
-
printContents
-
print contents pages
-
printContents: aList pageNumber: initialPageNumber romanPageNumbers: romanPageNumbers
-
print contents to destination
displaying
-
displayX: xLeft y: yTop width: w height: h on: aGC
-
self conditionalBreak.
-
pageBreak
-
(y > self pageBreakLimit and:[self atLeft and:[destination isView not]]) ifTrue:[
-
pageBreakLimit
-
-
redrawDocument
-
find a synchronization point
elements-document
-
body
-
destination defaultViewBackgroundColor
-
head
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
headEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
meta
-
already handled in parser ...
-
title
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
titleEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
elements-forms
-
anyFormElement: element
-
-
form
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
formEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
input
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
prescanForm: aFormElement
-
prescan a form, for its widgets max height.
a kludge - we need the form elements' heights BEFORE
formatting (since the text-elements have no origin knowledge,
which could be backpatched (also, we needed a way to break
MarkupText into multiple individual text items
-
prescanForms
-
a kludge - we need the form elements' heights BEFORE
formatting - since the text-elements have no origin knowledge,
which could be backpatched (also, we needed a way to break
MarkupText into multiple individual text items)
-
textarea
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
textareaEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
elements-lists
-
blockquote
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
blockquoteEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
dd
-
self conditionalBreak.
-
dir
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
dirEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
dl
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
dlEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
dt
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
li
-
this will ignore a followup BR or P
-
li_ol
-
this will ignore a followup BR or P
-
li_ul
-
in <ul> ... </ul> - draw a bullet
-
listTypeOfElement: anElement
-
-
menu
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
menuEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
ol
-
need to pass this info to </OL> element, for this to work
-
olEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
ul
-
need to pass this info to </UL> element, for this to work
usage example(s):
indent := element numericParameterFor:'INDENT' default:ULindent.
|
-
ulEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
elements-pseudo tags
-
internalMathFont
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
internalMathFontEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
elements-special
-
a
-
Transcript show:'a: '; show:needSpace; show:' '; showCR:anchorElement.
-
aEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
app
-
backward compatible (now obsolete) applet tag
-
appEnd
-
backward compatible (now obsolete) applet end-tag
-
applet
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
appletEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
area
-
self halt.
-
imageFor: urlString now: now
-
-
img
-
<IMG
SRC='image-url'
ALT='alternative-text'
WIDTH=w
HEIGHT=h
HSPACE=hSpc
VSPACE=vSpc
BORDER=bw
NOPRINT // deprecated
PRINT=yesOrNo // deprecated
LOWSRC='lowRes-image-url' // not implemented
STYLE='width:w; height:h'
>
-
map
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
mapEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
param
-
done in preparse - see #defineAppletParameterFor: ...
-
script
-
the script is now loaded and evaluated by the parser
(to allow it to generate the HTML text ...)
However, we need to remember it, for startup & cleanup message
sends.
-
specialMarkup
-
currentApplet notNil ifTrue:[
elements-structure
-
br
-
-
center
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
centerEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
div
-
w := element numericParameterFor:#'WIDTH' default:nil.
-
h1
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h1End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h2
-
-
h2End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h3
-
-
h3End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h4
-
-
h4End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h5
-
-
h5End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h6
-
-
h6End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h7
-
-
h7End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h8
-
-
h8End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
h9
-
-
h9End
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
hr
-
should come from a config or classVar
-
nobr
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
nobrEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
p
-
cg: no, a P is a P
usage example(s):
-
pEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
pre
-
self atLeft ifFalse:[ self break. ].
-
preEnd
-
if the last element was a newLine, remove it
-
tab
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
wbr
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
xmp
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
xmpEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
elements-style
-
acronym
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
acronymEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
address
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
addressEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
b
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
bEnd
-
inPre ~~ 0 ifTrue:[
-
cite
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
citeEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
code
-
(element hasParameterFor:'FOO') ifTrue:[self halt].
usage example(s):
codeFGColor notNil ifTrue:[self setColor:codeFGColor].
|
-
codeEnd
-
self handlePendingSpaceNeed.
-
dfn
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
dfnEnd
-
self handlePendingSpaceNeed.
-
em
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
emEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
font
-
self handlePendingSpaceNeed.
-
fontEnd
-
inPre ~~ 0 ifTrue:[
-
i
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
iEnd
-
inPre ~~ 0 ifTrue:[
-
kbd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
kbdEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
s
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
sEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
samp
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
sampEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
strike
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
strikeEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
strong
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
strongEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
sub
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
subEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
sup
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
supEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
tt
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
ttEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
u
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
uEnd
-
self handlePendingSpaceNeed.
-
var
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
varEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
elements-tables
-
caption
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
drawTable
-
-
drawTableRow: row
-
draw one row
-
finishPreviousTableColumn
-
'HTML [info]: empty table row' infoPrintCR.
-
finishPreviousTableRow: final
-
-
table
-
=fontDescent
usage example(s):
allow space for tables border
|
-
tableEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
tbody
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
tbodyEnd
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
td
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
th
-
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)
-
th_td_common
-
'pass1 col: ' print. currentColIndex print. ' x:' print. col x print. ' xT:' print. col xText printCR.
-
tr
-
allow space for tables leftborder
elements-text
-
addText: txtIn fromElement: element
-
Transcript show:'T: '; show:needSpace; show:' '; showCR:txtIn.
-
privateDrawString: aString atX: xS y: yS to: xE
-
formatting
-
flushAnchorColors
-
anchors notNil ifTrue:[
-
format: docAnchor for: aGC resolver: aResolver style: aStyle
-
loadedAppletClasses := nil.
-
process: aDocumentAnchor
-
skip upto applet end
-
reformatDocument
-
destination width == docWidth ifTrue:[
helpers
-
atLeft
-
-
atOrLeftOfLeft
-
-
atTop
-
-
break
-
-
conditionalBreak
-
break line if not already at the beginning
-
conditionalEmpty
-
add vertical space, but only if there is not already some
-
conditionalHalfEmpty
-
add vertical space, but only if there is not already some
-
currentElementHasHREF
-
-
do_needAndNewPage
-
handle any NEWPAGE and NEED= attributes of the current element,
put only if painting to paper (i.e. ignore if displaying)
-
do_starOfficeStyleBefore
-
handle
STYLE='page-break-before: always'
-
empty
-
-
empty: height
-
-
getFontsFor: aGC
-
-
halfEmpty
-
-
handlePendingSpaceNeed
-
-
header: index font: aFont space: space
-
don't break for headers within a list
-
headerEnd
-
-
initialHeaderNumbers
-
-
needSpace: nVerticalPixel
-
-
relativeValueFrom: aString with: aNumericValue
-
initialization
-
initialize
-
initialization & release
-
release
-
sent from docView, to release stuff
-
terminateMetaCommands
-
sent from docView, to release stuff
meta commands
-
processMetaCommands
-
Transcript showCR:metaCmd , ' -> ' , metaArg.
-
refreshDocument: url
-
private
-
addSyncPoint
-
-
displayImagesOn: destinationDevice usingPlayers: players
-
removeLast.
-
forkImageSequencePlayerFor: entry
-
-
handleColorAttribute
-
-
handleColorChange
-
-
playImageSequence: entry
-
get device images first ..
-
processFrom: firstElement while: aBlock
-
process elements starting with firstElement, while aBlock
returns true. Should be called from a saveExcursion block.
-
resyncFrom: syncPoint
-
fetch the state found there
-
saveExcursion: aBlock
-
save the current state, perform aBlock and restore the state afterwards
-
saveExcursionFrom: firstElement while: testBlock
-
remember the current state, process elements starting with firstElement,
while testBlock returns true, finally restore the state
-
setupInitialState
-
setup some initial state, such as margins, indents,
colors, fonts etc.
-
startImageDisplayProcess
-
handle two queues in the background; the first
contains images which are to be loaded (i.e. which are
contained in the current document) and have to be
rendered for the device.
The second contains those which are to be displayed.
The displayList is always served first.
-
syncPoint
-
save my state in a sync point
queries
-
anchorAt: aPoint
-
given a (click-) point, search for and return the corresponding
anchorElement. Return nil, if there is none
-
elementAt: aPoint
-
given a (click-) point, search for and return the corresponding
element. Return nil, if there is none
-
elementAt: aPoint type: typeOrNil
-
given a (click-) point, search for and return the corresponding
element. Return nil, if there is none
-
elementsDo: aBlock
-
enumerate the html elements
-
elementsWithType: typeOrNil do: aBlock
-
enumerate the html elements
-
height
-
-
imageAt: aPoint
-
given a (click-) point, search for and return the corresponding
imageElement. Return nil, if there is none
-
positionOfAnchor: aLocalAnchor
-
-
width
-
style changes
-
currentStyle
-
-
defaultStyle
-
-
getFontParameters
-
extra spacing.
-
normalStyle
-
-
popStyle
-
should not happen
-
pushStyle
-
-
setBGColor: aColor
-
-
setColor: aColor
-
-
setFont: aFont
-
self halt.
-
setStyle: aStyle
-
-
setUnderlineColor: aColor
-
widget-actions
-
buttonWidgetPressed: aWidgetElement
-
"/ pass it to the script object - if any.
-
formResetted: aFormElement from: aWidgetElement
-
reset forms contents to their original values
-
formSubmitted: aFormElement from: aWidgetElement
-
submit-button may still have an onClick... (nil if submitted via RETURN)
-
mouseOverAnchor: anElement
-
pass it to the script object - if any.
widgets
-
createWidgetFor: element inForm: aForm
-
widget backgroundColor:(destination viewBackground).
-
destroyWidgets
-
-
fixupForm: aForm
-
fixup the form: if there is a single inputField,
-
hideAllWidgets
-
hide any widget
-
hideWidgets
-
hide any widget which became invisible
-
prescanForm: aForm atIndex: startIndex
-
prescan a form, for its widgets max height.
a kludge - we need the form elements' heights BEFORE
formatting (since the text-elements have no origin knowledge,
which could be backpatched (also, we needed a way to break
MarkupText into multiple individual text items
-
showWidgets
-
show any widget which became visible
PainterState
TextStyle
WidgetQuery
|