Syntax10.Scn.Fnt ZStyleElemsAlloc TitleSyntax24.Scn.FntSyntax12.Scn.Fnt Courier12i.Scn.Fnt;qInfoElemsAllocNSyntax10.Scn.Fntv+IStampElemsAlloc6 Jan 99wAuthor: Andreas Helm Matr.Nr: 94 56 247 / 881 email: Andreas.Helm@jk.uni-linz.ac.at From: 28 May 98 Until: Syntax14.Scn.Fnt 0StampElemsAlloc6 Jan 99+Ԓ  Contents D'LineElemsAllocSyntax14b.Scn.FntLinkElemsAlloc*S\*A|! *X *~: *TU**A&*G*P(*LA*8V *ߗ- D'e+Ԓ  AfterContents@~ ChapterMarkElemsAllocS\u ListpBulletElemsAllocSyntax10i.Scn.Fnt_pp\ Normal-\u Listp* p  pppa)\@~ ChapterA|!XSyntax12b.Scn.Fnt " Syntax10b.Scn.FntSqPopupElemsAllocWebTables.Panel#Syntax10.Scn.FntPanel.Open WebTables.PanelJ$ 2'8 PElemsAllocBM6(Hpʦ  c \u Listp )\u# List26k K\u Listp )\u# List2D\ V \u Listp )\u# List27z"  H   w Normal+  L~: O> Syntax12m.Scn.Fntp  *L p  *7g= p  *= p  *= p  *= p  *= p  *Y= p  *P= p  *Z= p  *= p  *`= p  *= p  *= .qTablesSyntax10b.Scn.Fnt Syntax10.Scn.FntG;    9       9      Panel.Open WebTables.Panel ------------------------------------------- WebTables.Tables on WebTables.Tables off ------------------------------------------- WebTables.Refresh WebTables.Insert ^ WebTables.Remove WebTables.SetBorder ^ ------------------------------------------- WebTables.InsertColumns ^ WebTables.RemoveColumns ^ WebTables.InsertRows ^ WebTables.RemoveRows ^ ------------------------------------------- WebTables.CellSpan ^ WebTables.SetHeader ^ WebTables.InsertCell WebTables.RemoveCell  qWeb.Menu.Text#Syntax10.Scn.FntEdit.Open Web.Menu.Text EndList2L Syntax10m.Scn.Fnt  u# List2  EndList2$"*>7g= $  )\u# List2  )\ EndList22*>= q*>= `C*>=    )\u# List27)\ EndList2 5*>= '  )\u# List2$#Y EndList2  ]*>Y=  %  u# List2" S EndList2  [*>P=   u# List2Z EndList2  ^*>Z=    u# List2W EndList2  X*>=  #  u# List2O EndList2M*>`=    )\u# List2  EndList2 M*>=   r*>=   8 *>\ NormalTU ,\u Listy*)\@~ ChapterA; @$qWebPanelElems.Elem#Syntax10.Scn.FntEdit.Show WebPanelElems.Elem qWebCellElems.Elems#Syntax10.Scn.FntEdit.Show WebCellElems.Elem  6 ! KeplerElemsAllocKeplerGraphsGraphDescKeplerGraphsStarDesczz}Kepler2OffsetDescD|KeplerGraphsConsDesc}D| | { |}y|y|yD xDzKepler1RectangleDescKepler7TextDesc#Syntax10.Scn.Fnt table cell#Syntax10.Scn.Fnt table cell<Syntax10.Scn.Fnt Syntax10i.Scn.Fnt!table row ( = WebPanelElems.Elem) Kepler1AttrDesc     <Syntax10.Scn.Fnt Syntax10i.Scn.Fnt!table cell ( = WebCellElems.Elem)+hb  "(> ? O  ^G#k qHTML#Syntax10.Scn.FntEdit.Open HTML.Mod%\u Listp8p  , Courier10.Scn.Fnt)\u# ЌTypeDef - Courier10i.Scn.Fnt  9 # ; Z (  4  ( \u Listp `qAppendTextBuffer2#Syntax10.Scn.Fnt Edit.Show HTML.AppendTextBuffer24p qDoTag#Syntax10.Scn.FntEdit.Show HTML.DoTag'p  qShowFile#Syntax10.Scn.FntEdit.Show HTML.ShowFile4p WqSetTaskHandle#Syntax10.Scn.FntEdit.Show HTML.SetTaskHandle3p 09 qStoreBody#Syntax10.Scn.FntEdit.Show HTML.StoreBodyDp 0qInitSets#Syntax10.Scn.FntEdit.Show HTML.InitSets5pB qWebTables.maxWidthNSyntax10.Scn.FntLinkElemsAllocWebTables.Mod2)`qWebCellElems.normStyle#Syntax10.Scn.Fnt Edit.Show WebCellElems.normStyle\ Normal P qWebElems#Syntax10.Scn.FntEdit.Open WebElems.Mod%\u Listp  qFindElem#Syntax10.Scn.FntEdit.Show WebElems.FindElem qTableTools.FindElem#Syntax10.Scn.FntEdit.Show TableTools.FindElemp @` qFollowLink#Syntax10.Scn.FntEdit.Show WebElems.FollowLinkMp 09 qLinkImage#Syntax10.Scn.FntEdit.Show WebElems.LinkImage  qImageLinker#Syntax10.Scn.FntEdit.Show WebElems.ImageLinker @` qSetSource#Syntax10.Scn.FntEdit.Show WebElems.SetSource  qSetLoadResult#Syntax10.Scn.Fnt Edit.Show WebElems.SetLoadResult  qExchangePic#Syntax10.Scn.FntEdit.Show WebElems.ExchangePic  qAllImages#Syntax10.Scn.FntEdit.Show WebElems.AllImages #\ Normal  qFormElems#Syntax10.Scn.FntEdit.Open FormElems.Mod%\u Listp 0WqTwin#Syntax10.Scn.FntEdit.Show FormElems.Twin п qSubmitForm#Syntax10.Scn.FntEdit.Show FormElems.SubmitForm  ` qResetForm#Syntax10.Scn.FntEdit.Show FormElems.ResetForm  qTableTools.ReadElem#Syntax10.Scn.FntEdit.Show TableTools.ReadElem qTableTools.ReadPrevElem#Syntax10.Scn.Fnt!!Edit.Show TableTools.ReadPrevElem \ Normal pF qHandlerElems#Syntax10.Scn.FntEdit.Open HandlerElems.Mod%\u Listp @qHandlerElems.curHandle#Syntax10.Scn.Fnt Edit.Show HandlerElems.curHandlep p qSetHandler#Syntax10.Scn.Fnt!!Edit.Show HandlerElems.SetHandler P qResetHandler#Syntax10.Scn.Fnt##Edit.Show HandlerElems.ResetHandler# \ Normal ~qTextAreaElems#Syntax10.Scn.FntEdit.Open TextAreaElems.Mod%\u Listp 0 qFrameHandle#Syntax10.Scn.Fnt##Edit.Show TextAreaElems.FrameHandle1 \ NormalP:\u Listp ppp\ Normal#\u Listp pp\ Normal8\u Listp p p\ NormalLA%P  qTableTools.ReadElem#Syntax10.Scn.FntEdit.Show TableTools.ReadElem qTableTools.ReadPrevElem#Syntax10.Scn.Fnt!!Edit.Show TableTools.ReadPrevElem $@` qsection 3.1LSyntax10.Scn.FntLinkElemsAllocTables.TextA< @$qWebPanelElems.Elem#Syntax10.Scn.FntEdit.Show WebPanelElems.Elemj vqWebCellElems.Elem#Syntax10.Scn.FntEdit.Show WebCellElems.Elem+s vqWebCellElems.Elem#Syntax10.Scn.FntEdit.Show WebCellElems.Elem\   +௶Source   A  (  B\ NormalN `TqTableTools.ForAllFragments#Syntax10.Scn.Fnt$$Edit.Show TableTools.ForAllFragments)\@~ Chapter8Va \ w  A l-)\@~ Chapterߗ- ]\u ListpFp2 M p2pQpPA User's Guide Web-Tables Andreas Helm  Last change:   Contents 1 Introduction  2 User Interface  2.1 Panel  2.2 Commands  2.3 Tips  3 Programming  3.1 Implementation  3.2 Changes to the original browser  3.3 Modules and files  3.4 Iterating over a text with tables  4 Limitations  5 Problems   1 Introduction Web-Tables extend the Oberon web browser. They enable the browser to display tables in HTML documents. The following tags and attributes of tables are implemented:  The -tag with the BORDER attribute. The browser always displays a border of 1 pixel, but it stores the original value.  The -tag.  The
- and -tags with the attributes COLSPAN and ROWSPAN.  The following attributes are not supported:  The width and height attributes for the -tag and the
/ tags.  The attributes CELLSPACING and CELLPADDING of the -tags.  The attributes ALIGN and VALIGN for all table related tags.  The attribute NOWRAP of the tag, FALSE after tag *) next: State; (* Stack of States, for nested tables *) END;  The procedure  was modified to write in table cells if necessary.  The procedure  was modified to interpret table tags.  The procedure  was modified to write in table cells if necessary.  The procedure  was extended to initialise the new record fields.  The procedure  was extended to store tables and to make a "nice" output (indent).  The procedure  was extended to write the new supported tags in the tags-Array.  The module body was extended to initialise the public variables  and .  In the module , the following things were changed:  The procedure  was replaced by .  The procedure  was extended to reuse the same textframe, if a link in a table was clicked.  The procedures , , , , , and  were extended to look into tables.  In the module , the following things were changed:  The procedures ,  and  were modified to use  or  instead of Texts.ReadElem and Texts.ReadPrevElem.  In the module , the following things were changed:  The first handler () in the queue is exported.  The procedures  and  were extended to set the variable curHandle.  In the module , the following things were changed:  The procedure  was modified to call the current handler of the HandlerElems.  3.3 Modules and files The web browser was extended with the following modules:  WebPanelElems.Mod  WebCellElems.Mod  WebTables.Mod  TableTools.Mod  Changes were made in the modules:  HTML.Mod  WebElems.Mod  FormElems.Mod  The following (other) files also belong to web tables:  Tables.Text  Tables.Tool  WebTables.Panel  3.4 Iterating over a text with tables For normal iteration over a Web-text with tables, one might use the procedures  or . Both work on Text.Readers like the procedures of the same name in the module Text. The only difference to these procedures (in usage) is, that the reader may change during the iteration. This is because the procedures open new readers for the table cells. If your problem cannot be solved with the above procedures, the iteration is a bit more complicated than one might expect. An example code for an iteration over a text, including all (nested) tables, is shown below. To understand this code, one must understand the principle of the implementation of tables (see also ). Each row (in principle) of a table is assembled into one . Each panel has a text (elemTxt), which contains all embedded elements. In this text, all cells are nested (cells are represented with a ). Each WebCellElems.Elem contains a text (txt). If the table contains a nested table, it even gets more complicated: a panel is used to group the cell, and all  in this panel represent the cell. Between these "fragments", the nested tables are grouped. Therefore, one could use a variant of the following code to iterate over a text (To get more information about some elements in this code fragment, you can use the balloon help): PROCEDURE DoSomething(t: Texts.Text; pos: LONGINT; ...); VAR r: Texts.Reader; e: Texts.Elem; BEGIN IF t # NIL THEN Texts.OpenReader(r, t, pos); Texts.ReadElem(r); WHILE r.elem # NIL DO e := r.elem; WITH e: WebPanelElems.Elem DO (* Panel *) DoSomething(e.elemTxt, 0, ...) | e: WebCellElems.Elem DO (* cell(fragment) *) DoSomething(e.txt, 0, ...) ELSE (* other element *) ... END; Texts.ReadElem(r) END END END DoSomething;  If you are only interested in the text in all cells of a text, you might use . 4 Limitations Because of limitations of the Oberon system (no clipping for text elements), you may notice a strange behaviour, if a row of a table is too large to fit on the screen (You can see the same behaviour with the panel in Section 2, if the frame of this window is smaller than the panel height). To view these pages, you can turn the new implementation off (WebTables.Tables off) and reload the page. Afterwards, you can turn the new implementation on again by choosing WebTables.Tables on. Some Web pages, which are using forms and embed controls of the form into a table cannot be sent. By clicking on the Submit button the following message appears: "SubmitForm: Beginning Form-Tag expected! (pos 6)" This is because, these pages use code similar to this:
and tags.  The attributes, which change the colours of the background, the text of a table or the border. 2 User Interface 2.1 Panel To edit tables, you can use the , which looks like this:  Picture 1: WebTables.Panel You can open this document by clicking on the yellow question mark in the panel. Note: Most commands of the dialogue relate to a table or a cell. To specify a table simply set the caret into any of its cell. To specify a cell, you must set the caret into this cell. The dialogue is divided into the following three parts:  Operations on tables: The commands in this section manipulate whole tables. Refresh: Recalculates the dimensions of the table with the caret. If the caret is not in a table cell, all tables in the text with the caret get refreshed. Inspect: Inspect enters the number of columns, rows and the border width of the current table into the textfields. Set Border: Sets the border width of the current table to the value in the textfield. Remove: Deletes the current table. This command must be used to delete nested tables. If you want to delete an outmost table, you can delete it like normal text. Insert: Inserts a new table with the given dimensions into a text at the caret position. If the caret is in a table cell, a new nested table is created.  Operations on columns & rows: The commands in this section add/remove rows or columns to a table. Remove Columns: Removes the given number of columns, beginning with the column of the cell with the caret. Insert Columns: Inserts the given number of columns into a table. The combobox specifies, where the columns should be inserted. You can choose between left or right to the cell with the caret. Remove Rows: Removes the given number of rows, beginning with the row of the cell with the caret. Insert Rows: Inserts the given number of rows into a table. The combobox specifies, where the rows should be inserted. You can choose between above or below to the cell with the caret.  Operations on cells: The commands in this section manipulate a single cell. Inspect: Inspect enters the values for colspan and rowspan of the current cell into the textfields. If the cell is a header cell (-Tag), the checkbox gets checked. Set Span: Sets the colspan and rowspan values of the current cell to the values of the textfields. If you want to keep the same value, you can enter a 0 into the field. Set Header: Converts according to the check box the current cell in a header cell () or a data cell (). Remove Cell: Removes the current cell from the table. This works only for cells, which are adjacent to the right border of the table. If you want to remove a column, use Remove Columns instead. Insert Cell: Inserts a cell right beneath the current cell. This command is useful, if you edit a table, where cells are missing. If you prefer textual commands, the module WebTables offers the following commands, which are presented in the next section. 2.2 Commands The module WebTables offers the following commands for manipulating tables: Index:  Tables   Insert   Remove   Refresh   SetBorder   InsertColumns   InsertRows   RemoveColumns   RemoveRows   CellSpan   SetHeader   InsertCell   RemoveCell  To speed up work, you may enter this button () in your . Tables: Calling syntax: WebTables.Tables "on"|"off" data types: switch: STRING, "on" for new implementation, "off" for old implementation Uses the new table implementation ("on") or the default implementation ("off").  Back to the index Insert: Calling syntax: WebTables.Insert columns rows border data types: columns: INTEGER rows: INTEGER border: BOOLEAN or INTEGER Insert creates a new table and inserts it into a text.  Back to the index Remove: Calling syntax: WebTables.Remove Remove deletes the table with the caret. If this table is an outmost table, you might also delete it like normal text.  Back to the index Refresh: Calling syntax: WebTables.Refresh Refresh recalculates the measurement of the table with the caret. If the caret is not in a table cell, Refresh recalculates the width of all tables of the text with the caret.  Back to the index SetBorder: Calling syntax: WebTables.SetBorder border data types: border: INTEGER, border = 0 results in a table without border SetBorder sets the border width of the table with the caret.  Back to the index InsertColumns: Calling syntax: WebTables.InsertColumns ("l" |"r") num data types: where: CHAR; l = left of the cell with the caret, r = right of the cell with the caret num: INTEGER, number of columns to insert. If this parameter is missing, 1 column is inserted. InsertColumns inserts num columns in the table with the caret, left or right of the cell with the caret, depending on where.  Back to the index InsertRows: Calling syntax: WebTables.InsertRows ("a" |"b") num data types: where: CHAR; a = above the cell with the caret, b = below the cell with the caret num: INTEGER, number of rows to insert. If this parameter is missing, 1 row is inserted. InsertColumns inserts num rows in the table with the caret, above or below of the cell with the caret, depending on where.  Back to the index RemoveColumns: Calling syntax: WebTables.RemoveColumns num data types: num: INTEGER, number of columns to delete. If this parameter is missing, 1 column is deleted. RemoveColumns removes num columns from the table with the caret, starting with the column of the cell with the caret.  Back to the index RemoveRows: Calling syntax: WebTables.RemoveRows num data types: num: INTEGER, number of rows to delete. If this parameter is missing, 1 column is deleted. RemoveRows removes num rows from the table with the caret, starting with the row of the cell with the caret.  Back to the index CellSpan: Calling syntax: WebTables.CellSpan colSpan rowSpan data types: colSpan, rowSpan: INTEGER, new values for colspan and rowspan. A value of 0 keeps the old value. CellSpan sets the values of colspan and rowspan of the cell with the caret. To keep the old value, set the new value to 0.  Back to the index SetHeader: Calling syntax: WebTables.SetHeader header data types: header: BOOLEAN, TRUE for , FALSE for -cells SetHeader converts the cell with the caret into a header or into a normal data cell.  Back to the index InsertCell: Calling syntax: WebTables.InsertCell InsertCell creates a new cell right to the cell with the caret. This works only, if the position of the new cell is empty.  Back to the index RemoveCell: Calling syntax: WebTables.RemoveCell RemoveCell removes the cell with the caret from the table. One can only remove a cell from the last column of a table or a cell with colspan > 1, which overlaps the last columns. This procedure should not be used, it is better to leave the cell of the table empty instead of deleting it. To delete a column one should use RemoveColumn.  Back to the index  2.3 Tips To create a new table, follow these steps: 1. Place the cursor to the position, where the table should be created 2. Create the table with the panel or the command WebTables.Insert. You should create the table with border first, because it is easier to find. If you want a table without border, set the border to 0 after you have finished the table. 3. Enter the text of the table into the cells. To see, how the table will look later, set the cursor into a table cell and call WebTables.Refresh. 3 Programming 3.1 Implementation This section gives an overview of the implementation. A table consists of rows and columns. Because of limitations of the Oberon system, which does no clipping for text elements, it is impossible to implement a table as a single text element. Because of this, a more complex solution was used. Each table row is a . The cells of this row are . Picture 2 shows the principle:  Picture 2: Layout of a table cell. This implementation would work for simple tables without cells with rowspan > 1 or nested tables. For implementing nested tables, the chosen solution is a bit more complicated. Cells with nested tables look like this:  Picture 3: Nested tables The implementation of nested tables is, that the cell is no longer a WebCellElems.Elem, but a WebPanelElems.Elem contains the complete cell. The text of the cell (which is above, between and below of the nested tables) is stored in WebCellElems.Elems, which are dynamically linked. A nested table is implemented like a "normal" table. Another problem are cells with colspan and/or rowspan greater 1. Cells with colspan > 1 are rather simple to implement: Since the cell fits into one panel, nothing more has to be done. But cells with rowspan > 1 lead to the problem, that a cell would overlap two panels. Because of this, these rows are inserted into one panel:  Picture 4: cells with rowspan / colspan > 1 As you can see in picture 4, two rows are assembled to one WebPanelElems.Elem. 3.2 Changes to the original browser The following changes in the original browser were made to implement the new functionality. In the module , the following things were changed:  The table tags were added to the array of known tags.  The Type StateDesc was extended with the following variables: StateDesc = RECORD ... tabBorder: INTEGER; (* border width of the table *) writeToElem: BOOLEAN; (* TRUE, if text should be appended to curElem.txt *) head, curTable: WebTables.Table; (* temporary, only valid from "" to "
" *) curRow: WebTables.TableRow; curCell: WebTables.TableCell; curElem: WebCellElems.Elem; (* list of cells of the current table *) rowOpen: BOOLEAN; (* TRUE after
The Oberon browser uses special, invisible text elems for the tags
and
. Since the tag is not within a table cell, it is inserted before the table. Therefore the submit button first finds the tag instead of
and cannot send the information. To use these pages, turn the tables of with WebTables.Tables off. In some constellation it is possible, that rows of the same table have a different width. The reason for this behaviour is, that the Oberon system draws elements only once when they become visible. If you scroll afterwards, the element is only copied, but not redrawn. This is a problem, if another row of the table, which is wider, becomes visible. You can call WebTables.Refresh to fix this. Sometimes it is impossible to write in elements of a form, which are embedded in a table. To fix this, just set the caret in the text of the page and call WebTables.Refresh. Afterwards you can enter text in the form. 5 Problems The following problems, which occurred during the implementation, were the biggest for me:  The calculation of the size of the cells, when images were embedded.  The first implementation did not work, because a TextFrame does not send all messages to embedded elements, if it is nested in another Textframe.  Images in tables were loaded separately, because FindElem did not find them.  Clicks on links in table cells resulted in an opening of the pages in the cell.  Parallel loading of multiple pages caused problems in the list of active tasks.