HTML

HTML (HyperText Markup Language) is the language in which web pages are coded. The HTML unit of RFO-BASIC! lets a BASIC program present a web-page interface to the user. The BASIC program can obtain or generate HTML code in a string variable and have it treated as a web page, or can specify the address (URL) of a page on the web for display to the user.

However the HTML code is obtained, the web page is displayed under the control of the current version of Android WebView installed on the device. However, the BASIC program is in control of major user operations, such as following a hyperlink to a new page. The BASIC program can modify a web page before presenting it to the user. The web page can use JavaScript to send a message (a datalink) to the BASIC program.

Browsing occurs on a screen called the web screen, independent of the graphics screen and the text console.

The program  included in the RFO-BASIC! distribution is an example of a program that manages display of web pages. Two sample web pages used in this example,  and , are placed in BASIC's   directory during installation. It is instructive to read the code of this sample program, try it, and understand how the code produces the effects.
 * Examples

The program  included in the RFO-BASIC! distribution is a convenient text editor for the two demonstration web pages, or for other local web pages you may write.

Managing the unit
Like many other RFO-BASIC! units, the HTML. unit has initialization and termination statements.

HTML.OPEN
Initialize the HTML interface

HTML.OPEN { {, }}
 * Synopsis

The HTML.OPEN statement initializes the HTML. unit. The BASIC program must execute it before any other HTML. statements, and not do so a second time while the HTML. unit is active.
 * Description

If  is TRUE (nonzero), then the status bar appears on the web screen. If  is zero or omitted, there is no status bar.

If the statement includes , then it may also specify . If  is omitted, orientation of the web screen follows the general rules in effect for the Android device. This setting can be overridden later with HTML.ORIENTATION. Valid values for  are as follows:

HTML.CLOSE
Releases the HTML interface

HTML.CLOSE
 * Synopsis

The HTML.CLOSE statement releases all resources used by the HTML. unit. Resources are released automatically when the BASIC program stops executing.
 * Description

Displaying HTML
HTML code can be displayed, obtained from a string expression inside the BASIC program using HTML.LOAD.STRING, or from the web using HTML.LOAD.URL.

HTML.LOAD.STRING
Display HTML from a BASIC string

HTML.LOAD.STRING 
 * Synopsis

The HTML.LOAD.STRING statement takes HTML code from the specified string expression and displays it as a web page.
 * Description

This code generates a trivial web page and displays it. HtmlCode$ = "Sample pageThis is the text of my tiny web page.</HTML>" HTML.LOAD.STRING HtmlCode$
 * Examples

More realistically, a program could download a web page into a string variable, make any desired changes to it — This example assumes you have written a user-defined function  to do so — and display the modified page:

GRABURL Page$,"https ://rfobasic.miraheze.org" ModifyWebPage(&Page$)  ! Your user-defined function makes any desired changes HTML.LOAD.STRING(Page$) ! and display the modified web page

HTML.LOAD.URL
Display HTML from a web page

HTML.LOAD.URL <file_sexp>
 * Synopsis

Instead of taking HTML code out of a string expression, HTML.LOAD.URL interprets its string expression <file_sexp> as the name of the place where the code resides. HTML.LOAD.URL "https ://rfobasic.miraheze.org" HTML.LOAD.URL "htmlDemo1.html" HTML.LOAD.URL "file:///sdcard/rfo-basic/data/htmlDemo1.html"
 * Description
 * If it begins with a protocol, such as  or , then the string expression is interpreted as an Internet URL (Universal Resource Locator) and BASIC obtains the web page from that location on the web.  The statement gives a run-time error if there is no way (WiFi, cellphone data, or other) to get pages from the web.  For example:
 * If it is an ordinary filename, then BASIC obtains the web page from a file on your Android device. BASIC assumes the file is in the   directory on the device where RFO-BASIC! was installed (normally, the SD card).  The demonstration program executes:
 * If it is a fully-qualified filename, then BASIC obtains the web page from the named file. (This does not work if you do not have access to the root of your Android device's file system.)  The following statement has the same effect as the previous example, if you have access to such a filename:

GRABURL
GRABURL is a subset of HTTP.REQUEST. It fails on Android 9 and newer. Aspects of it assume unscrambled transfers, but newer Android versions require scrambled  transfers for security. A workaround is to provide a URL to BYTE.OPEN; any web page can be retrieved as a "byte file." </DIV> Obtain the text of a web page

GRABURL <result_svar>, <url_sexp>{, <timeout_nexp>}
 * Synopsis

The preceding statements use your device's browser to display a web page or other HTML text. The GRABURL statement gets the source text of a web page in <result_svar>.

Similar to the <file_sexp> parameter of HTML.LOAD.URL, the <url_sexp> parameter of GRABURL specifies the location of the desired page.
 * The parameter must begin with a protocol, such as  or  .  The string expression is interpreted as an Internet URL (Universal Resource Locator) and BASIC obtains the web page from that location on the web.  If the URL does not exist or if there is no way (WiFi, cellphone data, or other) to get pages from the web, then <result_svar> is set to the empty string, "", and the GETERROR$ function returns additional information.
 * If it is a fully-qualified filename, then BASIC obtains the web page from the named file. (This does not work if you do not have access to the root of your Android device's file system.)

If the <timeout_nexp> parameter is present and if its value is non-zero, it specifies a timeout in milliseconds. This is meaningful only if the URL names a resource on a remote host. If the timeout time elapses and host does not connect or does not return any data, GETERROR$ reports a socket timeout.

If the named resource is empty, the <result_svar> is empty, "", and GETERROR$ returns "No error".

The SPLIT statement can be used to split <result_svar> into an array of lines.

The following statement obtains, in A$, the main page of this wiki: GRABURL A$, "https ://rfobasic.miraheze.org"
 * Examples

The following statement obtains the text of a demonstration web page from the distributed samples: GRABURL A$, "file:///sdcard/rfo-basic/data/htmlDemo1.html" Replace  with the correct pathname for the RFO-BASIC! root directory on the storage device on which you installed it. This varies among Android devices.

Managing a browsing session
The user can scroll through the web page, may be able to zoom in and out, and may be able to operate the user interface elements of the web page, without the participation of the BASIC program. However, every user action that implies going to a different web page, plus certain other actions, is communicated to the BASIC program and requires the support of the BASIC program to carry out the action.

The BASIC program may receive datalinks from the browser. A datalink is a string, which the BASIC program stores in a string variable. The first four characters of each datalink indicates what the user did that requires the program's attention. The BASIC program does not have to process datalinks as fast as the browsing session generates them; BASIC buffers them and presents each to the program in sequence.

HTML.GET.DATALINK
Get one datalink

HTML.GET.DATALINK, then the operation is valid (there is a web page to go back to). If the BASIC program elects to let the user go to that webpage, it executes. If the datalink is, then there is no web page to go back to; for instance, the user may be trying to go "back" before the original web page. The browsing session ends and BASIC displays the text console, where the program can tell the user what happened, such as with  statements.
 * Synopsis
 * STYLE="font-family: monospace" | DAT:
 * The web page has sent a message to the BASIC program, as described below. The rest of the datalink is the message.
 * STYLE="font-family: monospace" | DNL:
 * The user has clicked on a link meant to start a download. The rest of the datalink is the URL of the information to be downloaded.  To carry out the user's intent to download the data, the program executes code like this:
 * STYLE="font-family: monospace" | DNL:
 * The user has clicked on a link meant to start a download. The rest of the datalink is the URL of the information to be downloaded.  To carry out the user's intent to download the data, the program executes code like this:


 * STYLE="font-family: monospace" | ERR:
 * An error has occurred that prevents the browsing session from continuing. The rest of the datalink is text describing the error.  The browsing session ends and BASIC displays the text console, where the program can tell the user what happened, such as with   statements.
 * STYLE="font-family: monospace" | FOR:
 * The user has filled out a form in a web page and tapped a button the web page defines as the SUBMIT button. The rest of the datalink is name/value pairs.  See below.
 * STYLE="font-family: monospace" | LNK:
 * The user has tapped a hyperlink. The rest of the datalink is the URL of the web page it links to.  The BASIC program may elect to surf to that web page (or to some other web page).  To carry out the user's intent to go to a linked page, the program executes code like this:
 * STYLE="font-family: monospace" | LNK:
 * The user has tapped a hyperlink. The rest of the datalink is the URL of the web page it links to.  The BASIC program may elect to surf to that web page (or to some other web page).  To carry out the user's intent to go to a linked page, the program executes code like this:
 * The user has tapped a hyperlink. The rest of the datalink is the URL of the web page it links to.  The BASIC program may elect to surf to that web page (or to some other web page).  To carry out the user's intent to go to a linked page, the program executes code like this:


 * STYLE="font-family: monospace" | STT:
 * The user has spoken to the web page. The BASIC program can use the STT.RESULTS statements to get Google's interpretation of the speech into a list.  The most likely interpretation is in element 1 of the list.  The program can interpret the user's speech as desired.
 * }
 * }

Forms in a web page
A web page can contain forms. A form is a web page element that has input elements, such as fields to fill out, check boxes, radio boxes, and buttons that can be tapped.

A BASIC program might be accompanied by a local web page that is nothing but a form, and whose only function is to be the user interface for the BASIC program (as opposed to input using the text console or graphics screen).

Here is a bare-bones form in HTML:

<FORM> <LABEL>First name: <INPUT ID="field" NAME="firstname" /> </LABEL> <BR /> <LABEL>Last name: <INPUT ID="field2" NAME="lastname" /> </LABEL> <BR /> <INPUT type="submit" /> </FORM>

When the user presses the button whose type is "submit", then the web page sends a  datalink to the BASIC program. The datalink contains:
 * The header  indicating that it is information from a form.
 * The complete URL of the web page that sent the form.
 * The character  followed by the name-and-value pair for the first field.
 * The character  followed by the name-and-value pair for any additional fields.

For example: FOR:file:///storage/sdcard/rfobasic/data/tester.htm?firstname=John&lastname=Doe

If the purpose of the form was to let the user identify a person, then the BASIC program might now compose another web page that had relevant information it had on that person and restart the browsing session with that web page.

In Android devices with newer Webview components, pressing the button whose type is "submit" begins a two-stage process. The web page sends a  datalink to the BASIC program.
 * Newer browsers

For example: LNK:file:///storage/sdcard/rfobasic/data/tester.htm/FORM?firstname=John&lastname=Doe

When the BASIC program submits this URL (stripping off the ), the web page sends the   datalink. However, "Web page not available" flashes briefly, because  is not a valid web page. Alternatively, the BASIC program can extract the name-and-value pairs from the  string and not trigger the   datalink at all:

IF type$ = "LNK:" THEN p = IS_IN("FORM?",data$) IF p THEN data$=mid$(data$, p+5) ENDIF

Sending messages to the BASIC program
In the event that a web page is invoked by a BASIC program, JavaScript code in the web page can send a text message to the BASIC program using the  function. The single parameter of this function is a text string to send to the BASIC program. Calling this function sends a datalink with header. For example, the web page might contain this JavaScript:

<script type="text/javascript"> function doDataLink(data) { Android.dataLink(data); } /* Follow with other JavaScript code that generates the message and * calls doDataLink. */

Miscellaneous statements
The following statements let the BASIC program take more detailed control of the browsing session:

Issuing a POST to a web server
Private version

OLI-BASIC provides a more complete HTTP.REQUEST statement. It can generate a request using the GET method (in which the name/value pairs are appended to the URL for the server) as well as the POST method shown here. </DIV> In the POST method of querying a web server, a BASIC program sends name/value pairs to the server. For example, the BASIC program might want to retrieve the employee ID number of a person. The essence of the request is as follows:

The HTML.POST statement makes such a request, provided that the BASIC program has executed HTML.OPEN, and uses the WebView capability of the Android device to display the resulting web page. The HTTP.POST statement makes a stand-alone request and captures the result into a string variable.

Both BASIC statements require that the list of name/value pairs be placed in a string list. The odd entries (starting with the first) are the names and the even entries (starting with the second) are the corresponding values.

A Hypertext Transfer Protocol (HTTP) request sent to a server has a request header specifying a Content-Type of: Content-Type: application/x-www-form-urlencoded
 * Format of request

Although POST requests have many other capabilities, such as the ability to send other content-types and to send cookies, there is no way to do so in RFO-BASIC!.

The name/value pairs in the string list follow the request header; that is, they are the body of the message. In the above example, the HTTP request might look like this: POST /foo.php HTTP/1.1 Host: ExampleServer.com User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Content-Type: application/x-www-form-urlencoded Content-Length: 54 FirstName=Fred&LastName=Smith&RequestedData=EmployeeID

A server that allows such a request will reply with the RequestedData in some agreed-on format.

In the GET method, the name/value pairs are not the body of the message but are included in the URL, following a  character. RFO-BASIC! has no statements to issue a GET. However, the program can do it itself. The simplest way to do so is to append the name/value pairs to the name of the desired web page. For example: ExampleServer.com?FirstName=Fred&LastName=Smith&RequestedData=EmployeeID
 * Issuing a GET

The resulting string could be the parameter to a GRABURL statement. As before, the website would have to be designed to accept a request in this format.

HTML.POST
Issue a POST request to a website

HTML.POST <url_sexp>, <list_nexp>
 * Synopsis

The HTML.POST statement submits name/value pairs contained in the string list <list_nexp> to the website named in <url_sexp>. If the website responds by providing a web page, then the user is able to view it, and can interact with it like any other web page opened by the HTML. unit.
 * Description

Continuing the example in the overview, we place in a string list the name/value pairs for a request to a server.
 * Example

LIST.CREATE S PersonnelList    % BASIC returns a pointer to the new list LIST.ADD PersonnelList, "FirstName", "Fred", ~ "LastName", "Smith", ~ "RequestedData", "EmployeeID" HTML.POST "http ://ExampleServer.com", PersonnelList

The result of this sequence will be that the user is taken to a web page that presumably displays the desired employee ID.

HTTP.POST
Issue a POST request to a website

HTTP.POST <url_sexp>, <list_nexp>, <result_svar>
 * Synopsis

The HTTP.POST statement is another way of formulating a request to a web server that is independent of the HTML. unit and does not result in a user browsing session. It submits name/value pairs contained in the string list <list_nexp> to the website named in <url_sexp> and captures the result in <result_svar>.
 * Description

Again continuing the example in the overview, we place in a string list the name/value pairs for a request to a server.
 * Example

LIST.CREATE S PersonnelList    % BASIC returns a pointer to the new list LIST.ADD PersonnelList, "FirstName", "Fred", ~ "LastName", "Smith", ~ "RequestedData", "EmployeeID" HTTP.POST "http ://ExampleServer.com", PersonnelList, Result$

The result of this sequence will be that the web page emitted by the server is captured in Result$ for analysis by the BASIC program.

Since HTTP.POST does not depend on the HTML. unit or on an active browsing session, the name/value pairs can be submitted to a website or even to a web page that resides on the Android device:

HTTP.POST "file :///MyLookup.htm", PersonnelList, Result$

Problematic web pages
The HTML. unit may have problems displaying web pages that:
 * 1) Open additional windows with which to interact with the user.
 * 2) Use the BACK key for purposes other than returning to a previous web page.

Editor's query

 * In Sending messages to the BASIC program above, the code is based on the code in the original manual. I don't see the reason for the wrapper function.