An experimental implementation of javascript in Amaya

Introduction

Presentation

Screenshot of Amaya with javascript enabled

The goal of the project is to implement Javascript - aka Ecmascript - and DOM in Amaya. I have already integrated "SpiderMonkey", the Mozilla's interpreter, but there is still a lot of work to do for DOM. As I wrote to the Amaya mailing list, this project is motivated by the fact it follows two main purposes of Amaya :

  1. Creating a software that demonstrate W3C technologies

    Javascript is not a W3C standard but is regarded by several people as a basic feature of Web browsers. Hence it is a bit paradoxical to have in the one hand state-of-art W3C technologies and on the other hand no scripting capability.

    DOM is part of the W3C specifications and so it is natural to implement it if we want to achieve the goal of a W3C browser/editor. But I think we can moreover get features that other browsers do not have :

  2. Being used by every level of users to produce documents conformed to W3C specifications

    Javascript is both for a beginner (because the syntax is simple) and an advanced user (because it allows sophisticated AJAX interface). So an implementation in Amaya (with state-of-art XML languages) is required for the latter and a help to easy write scripts conformed to W3C specification is useful for the former (sadly enough, a lot of them use a non-standard DOM, specific to Internet Explorer).

If you have any comment or want to help me, then you can write to the mailing list : www-amaya (discussion about general issues) or www-amaya-dev (technical discussion).

Installation

  1. Download and compile Amaya using the CVS version following the instructions given on the website
  2. Install the development files for the SpiderMonkey. The Debian package is libmozjs-dev
  3. Apply the patch makefile.diff to Amaya/amaya/Makefile.in
  4. In Amaya/WX/Options, add the flag -D_JAVA to AMAYA_OPTIONS=
  5. In Amaya/config/amaya.profiles, remove the # before +javascript_dom
  6. In Amaya/amaya, compile the files EDITORactions.c, init.c, javascript.c

TODO : modify the configure.in to generate a configure script that accepts the option --with-javascript.

Overview

Switching ON/OFF the Javascript engine

Amaya is both a browser and an editor : on the one hand you expect to find the same features as the other browsers but in the other hand you want specific authoring tools. This issues have already be met with links or forms and are even more true in the case of scripting. Because when you edit a document, you do not want the scripts to interfere with your actions, the Javascript engine of Amaya can be switch ON/OFF.

Javascript menu with (javascript disabled)

To avoid the use of memory by the Javascript engine - not supposed to be used in all Web pages - and for security reasons, it is initially switch OFF when a page is (re)loaded. Of course an option could be to automatically switch ON the Javascript engine. The Javascript engine is also switch OFF as soon as SpiderMonkey find an error or when the user modify the document.

When you are writing your script, you can make mistakes and get an infinite loop. Hence during an execution, the routine that checks the actions of the user (TtaHandlePendingEvents) is regurlarly called, so that it is always possible to interrupt the script. As an example, try to execute something like :

while(true);

For the sake of simplicity, I chosed in a first time to only allow the execution of scripts in one document at a time and in formatted view.

Executing scripts

Once the javascript engine is ON, all the scripts contained in the document are loaded and executed. The javascript functions are not generally called just after page is loaded but rather after an event such as onclick. Such events are not implemented yet but as for links and forms, Amaya should have a different behaviour.

Entering a Javascript Command

When editing a script, the user often wants to do debbuging actions. A dialog box where the user can enter a command is available. This also allows to execute functions that are normally called after an event. Other browsers allow to execute a command using "javascript:" in the adress bar. Must this feature be implemented ? Also, because all the XML documents can not contain <script> element - for instance MathML or SVG documents - a menu allows to choose and execute an external script in the current document if necessary. This is not implemented yet.

Finally, when an error occured during a script execution the file, the line and the message error are displayed. This helps the user to debug the code.

A message error

Writing scripts

There are two classical ways to use Javascript in Web pages. Either you directly enter your code in the source of the document inside a <script> element, or you use an external script whose location is described by the src attribute of a <script> element. Amaya already allows the first method (using XHTML -> Structure -> Script) but I also put this entry in the Javascript/DOM menu. For XML document, Amaya should add a CDATA section rather than a Comment. An entry to "Add an external script" is also available.

Open a Javascript File

For entering the Javascript code, I add the (*.js) extension to the list of known files, so the user can open a javascript file as text and edit the source code. Amaya is not likely to propose more than other programming software. Nonetheless, DOM 1 specification indicates that "DOM names tend to be long and quite descriptive in order to be unique across all environment" so we can imagine a DOM panel to insert these names in the source code.This could help users to respect the DOM standard.

Status of the implementation

Javascript in Web pages

Amaya can execute scripts contained in (X)HTML documents, in the same way as other browsers do. The script must be either in the <head> or in the <body> and the code inside a <script> - possibly with HTML comment/CDATA section. Also, you can use the src attribute to use an external js file.

The interpretation of external js file only worked with local file, so I have to rewrite it.

For the moment, Amaya does not handle Javascript events such as onclick. Nevertheless, it is always possible to reproduce the action using the "Execute a command" form where you copy and paste the attribute.

Executing scripts in XML documents whose DTD do not allow the <script> element is not possible yet.

The javascript objects, methods and properties

The Javascript code is handled by SpiderMonkey and as a consequence, at less all the scripts that do not require the intervention of Amaya are available (variables, for, do-while, if-else...). As an example, I made a little game.

Additionaly, a structure compatible with the one of classical browsers has been integrated to ask Amaya to give its properties or to make actions:

Window (global object)
  |
  |_ Navigator
  |
  |_ Screen
  |
  |_ History
  |
  |_ Location
  |
  |_ Document

The object Document is described in the next section, it is actually part of the DOM specification. To get more information about the properties and methods of the other objects see javascript.h andjavascript.c. Note that as in Firefox, Window is not really the name of the global object, but one of its property that returns itself.

All the properties and methods common to other browsers have been listed in javascript.h, but the implementation in javascript.c is not finished yet. Nevertheless, some important features are avalaible among the one implemented :

DOM implementation

Document Object Model Level 1 Core

Some basic ways to access a node in the tree are available (FirstChild, NextSibling, childNodes.item()...) and you can get information on a node with the nodeType, nodeName and nodeValue properties. The scan_tree file analyses the tree of a document.

Currently, methods to modify the DOM tree are really limited... I have disabled them because I have to rewrite some part of the code to be compatible with the new JSAPI (1.9).

Here is the detailed implementation status :

Object DOMException - NO
Object ExceptionCode - PARTIAL
Object DOMImplementation - PARTIAL
hasFeature(feature, version) - PARTIAL
Object DocumentFragment - NO
Object Document - PARTIAL
doctype - PARTIAL
implementation - PARTIAL
documentElement - YES
createElement(tagName) - NO
createDocumentFragment() - NO
createTextNode(data) - NO
createComment(data) - NO
createCDATASection(data) - NO
createProcessingInstruction(target, data) - NO
createAttribute(name) - NO
createEntityReference(name) - NO
getElementsByTagName(tagname) - YES disabled
Object Node - PARTIAL
nodeName - PARTIAL
nodeValue - PARTIAL
nodeType - PARTIAL
parentNode - YES
childNodes - YES
firstChild - YES
lastChild - YES
previousSibling - YES
nextSibling - YES
attributes - PARTIAL disabled
ownerDocument - YES
insertBefore(newChild, refChild) - NO
replaceChild(newChild, oldChild) - NO
removeChild(oldChild) - NO
appendChild(newChild) - NO
hasChildNodes() - YES
cloneNode(deep) - NO
Object NodeList - YES
length - YES
item(index) - YES disabled
Object NamedNodeMap - PARTIAL
length - NO
getNamedItem(name) - PARTIAL disabled
setNamedItem(arg) - NO
removeNamedItem(name) - NO
item(index) - NO
Object CharacterData - NO
data - NO
length - NO
substringData(offset, count) - NO
appendData(arg) - NO
insertData(offset, arg) - NO
deleteData(offset, count) - NO
replaceData(offset, count, arg) - NO
Object Attr - NO
name - NO
specified - NO
value - NO
Object Element - PARTIAL
tagName - YES
getAttribute(name) - NO
setAttribute(name, value) - NO
removeAttribute(name) - NO
getAttributeNode(name) - NO
setAttributeNode(newAttr) - NO
removeAttributeNode(oldAttr) - NO
getElementsByTagName(name) - YES disabled
normalize() - NO
Object Text - PARTIAL
splitText(offset) - NO
Object Comment - PARTIAL
Object CDATASection - PARTIAL
Object DocumentType - PARTIAL
name - NO
entities - NO
notations - NO
Object Notation - NO
publicId - NO
systemId - NO
Object Entity - NO
publicId - NO
systemId - NO
notationName - NO
Object EntityReference - NO
Object ProcessingInstruction - NO
target - NO
data - NO

Document Object Model Level 1 HTML

Object HTMLCollection - NO
length - NO
item(index) - NO
namedItem(name) - NO
Object HTMLDocument - NO
title - NO
referrer - NO
domain - NO
URL - NO
body - NO
images - NO
applets - NO
links - NO
forms - NO
anchors - NO
cookie - NO
open() - NO
close() - NO
write(text) - NO
writeln(text) - NO
getElementById(elementId) - NO
getElementsByName(elementName) - NO
Object HTMLElement - NO
id - NO
title - NO
lang - NO
dir - NO
className - NO
Object HTMLHtmlElement - NO
version - NO
Object HTMLHeadElement - NO
profile - NO
Object HTMLLinkElement - NO
disabled - NO
charset - NO
href - NO
hreflang - NO
media - NO
rel - NO
rev - NO
target - NO
type - NO
Object HTMLTitleElement - NO
text - NO
Object HTMLMetaElement - NO
content - NO
httpEquiv - NO
name - NO
scheme - NO
Object HTMLBaseElement - NO
href - NO
target - NO
Object HTMLIsIndexElement - NO
form - NO
prompt - NO
Object HTMLStyleElement - NO
disabled - NO
media - NO
type - NO
Object HTMLBodyElement - NO
aLink - NO
background - NO
bgColor - NO
link - NO
text - NO
vLink - NO
Object HTMLFormElement - NO
elements - NO
length - NO
name - NO
acceptCharset - NO
action - NO
enctype - NO
method - NO
target - NO
submit() - NO
reset() - NO
Object HTMLSelectElement - NO
type - NO
selectedIndex - NO
value - NO
length - NO
form - NO
options - NO
disabled - NO
multiple - NO
name - NO
size - NO
tabIndex - NO
add(element, before) - NO
remove(index) - NO
blur() - NO
focus() - NO
Object HTMLOptGroupElement - NO
disabled - NO
label - NO
Object HTMLOptionElement - NO
form - NO
defaultSelected - NO
text - NO
index - NO
disabled - NO
label - NO
selected - NO
value - NO
Object HTMLInputElement - NO
defaultValue - NO
defaultChecked - NO
form - NO
accept - NO
accessKey - NO
align - NO
alt - NO
checked - NO
disabled - NO
maxLength - NO
name - NO
readOnly - NO
size - NO
src - NO
tabIndex - NO
type - NO
useMap - NO
value - NO
blur() - NO
focus() - NO
select() - NO
click() - NO
Object HTMLTextAreaElement - NO
defaultValue - NO
form - NO
accessKey - NO
cols - NO
disabled - NO
name - NO
readOnly - NO
rows - NO
tabIndex - NO
type - NO
value - NO
blur() - NO
focus() - NO
select() - NO
Object HTMLButtonElement - NO
form - NO
accessKey - NO
disabled - NO
name - NO
tabIndex - NO
type - NO
value - NO
Object HTMLLabelElement - NO
form - NO
accessKey - NO
htmlFor - NO
Object HTMLFieldSetElement - NO
form - NO
Object HTMLLegendElement - NO
form - NO
accessKey - NO
align - NO
Object HTMLUListElement - NO
compact - NO
type - NO
Object HTMLOListElement - NO
compact - NO
start - NO
type - NO
Object HTMLDListElement - NO
compact - NO
Object HTMLDirectoryElement - NO
compact - NO
Object HTMLMenuElement - NO
compact - NO
Object HTMLLIElement - NO
type - NO
value - NO
Object HTMLBlockquoteElement - NO
cite - NO
Object HTMLDivElement - NO
align - NO
Object HTMLParagraphElement - NO
align - NO
Object HTMLHeadingElement - NO
align - NO
Object HTMLQuoteElement - NO
cite - NO
Object HTMLPreElement - NO
width - NO
Object HTMLBRElement - NO
clear - NO
Object HTMLBaseFontElement - NO
color - NO
face - NO
size - NO
Object HTMLFontElement - NO
color - NO
face - NO
size - NO
Object HTMLHRElement - NO
align - NO
noShade - NO
size - NO
width - NO
Object HTMLModElement - NO
cite - NO
dateTime - NO
Object HTMLAnchorElement - NO
accessKey - NO
charset - NO
coords - NO
href - NO
hreflang - NO
name - NO
rel - NO
rev - NO
shape - NO
tabIndex - NO
target - NO
type - NO
blur() - NO
focus() - NO
Object HTMLImageElement - NO
lowSrc - NO
name - NO
align - NO
alt - NO
border - NO
height - NO
hspace - NO
isMap - NO
longDesc - NO
src - NO
useMap - NO
vspace - NO
width - NO
Object HTMLObjectElement - NO
form - NO
code - NO
align - NO
archive - NO
border - NO
codeBase - NO
codeType - NO
data - NO
declare - NO
height - NO
hspace - NO
name - NO
standby - NO
tabIndex - NO
type - NO
useMap - NO
vspace - NO
width - NO
Object HTMLParamElement - NO
name - NO
type - NO
value - NO
valueType - NO
Object HTMLAppletElement - NO
align - NO
alt - NO
archive - NO
code - NO
codeBase - NO
height - NO
hspace - NO
name - NO
object - NO
vspace - NO
width - NO
Object HTMLMapElement - NO
areas - NO
name - NO
Object HTMLAreaElement - NO
accessKey - NO
alt - NO
coords - NO
href - NO
noHref - NO
shape - NO
tabIndex - NO
target - NO
Object HTMLScriptElement - NO
text - NO
htmlFor - NO
event - NO
charset - NO
defer - NO
src - NO
type - NO
Object HTMLTableElement - NO
caption - NO
tHead - NO
tFoot - NO
rows - NO
tBodies - NO
align - NO
bgColor - NO
border - NO
cellPadding - NO
cellSpacing - NO
frame - NO
rules - NO
summary - NO
width - NO
createTHead() - NO
deleteTHead() - NO
createTFoot() - NO
deleteTFoot() - NO
createCaption() - NO
deleteCaption() - NO
insertRow(index) - NO
deleteRow(index) - NO
Object HTMLTableCaptionElement - NO
align - NO
Object HTMLTableColElement - NO
align - NO
ch - NO
chOff - NO
span - NO
vAlign - NO
width - NO
Object HTMLTableSectionElement - NO
align - NO
ch - NO
chOff - NO
vAlign - NO
rows - NO
The HTMLTableSectionElement object has the following methods:
insertRow(index) - NO
deleteRow(index) - NO
Object HTMLTableRowElement - NO
rowIndex - NO
sectionRowIndex - NO
cells - NO
align - NO
bgColor - NO
ch - NO
chOff - NO
vAlign - NO
insertCell(index) - NO
deleteCell(index) - NO
Object HTMLTableCellElement - NO
cellIndex - NO
abbr - NO
align - NO
axis - NO
bgColor - NO
ch - NO
chOff - NO
colSpan - NO
headers - NO
height - NO
noWrap - NO
rowSpan - NO
scope - NO
vAlign - NO
width - NO
Object HTMLFrameSetElement - NO
cols - NO
rows - NO
Object HTMLFrameElement - NO
frameBorder - NO
longDesc - NO
marginHeight - NO
marginWidth - NO
name - NO
noResize - NO
scrolling - NO
src - NO
Object HTMLIFrameElement - NO
align - NO
frameBorder - NO
height - NO
longDesc - NO
marginHeight - NO
marginWidth - NO
name - NO
scrolling - NO
src - NO
width - NO
This page is W3C-compliant - Author:
Valid XHTML 1.1 Valid MathML 2.0 Valid SVG Valid CSS