--- layout: default title: Amber Smalltalk - documentation ---

# Documentation

## Disclaimer

This documentation is a work in progress. If you find an error in the documentation, please file an issue.

This documentation doesn't aim to teach Smalltalk. Knowledge of Smalltalk is needed to understand the topics covered in this documentation. If you want to learn the Smalltalk language, you can read the excellent Pharo By Example book.

## Introduction

Amber is a young piece of code and evolves quickly. Some features are still incomplete and you may very well encounter bugs, in which case you can file an issue or a pull request on the repository.

Amber is an implementation of the Smalltalk-80 language. It allows developers to write client-side heavy web applications in Smalltalk. Amber includes an integrated development environment with a class browser, workspace and transcript.

Amber includes the following features:

1. It is semantically and syntaxically equivalent to Pharo Smalltalk (the implementation considered as the reference)
2. It is written in itself and compiles into efficient JavaScript
3. A canvas API similar to Seaside to generate HTML
4. A jQuery binding

## Differences with other Smalltalk implementations

Amber has some differences with other Smalltalk implementations. Because it maps Smalltalk constructs one-to-one with the JavaScript equivalent, including Smalltalk classes to JavaScript constructors, the core class library is simplified compared to Pharo Smalltalk. The following list explains the main differences:

- There is no identity in Amber. Especially, there is no `==` method, or `Symbol` class. For convenience and compatibility, the Amber parser will recognize symbol literals as strings.
- The collection class hierarchy is simpler compared to most Smalltalk implementations. There is no `OrderedCollection`, `Set` or `SortedCollection`. However, the size of arrays is dynamic, and they behave like an ordered collection. They can also be sorted with the `#sort*` methods.
- The `Date` class behaves like the `Date` and `TimeStamp` classes in Pharo Smalltalk. Therefore both `Date today` and `Date now` are valid in Amber.
- Amber use solely `=` to test object equality and not the `#hash` method.
- Amber misses `thisContext`. Amber now supports `thisContext`
- Amber does not support `#doesNotUnderstand`. Amber now has support for `#dnu:`.

## Committing changes to disk with the web-based IDE

The class browser is able to commit changes to disk. The `commit category` button will send a PUT request with the compiled JavaScript code of all classes in the selected class category in a file named `js/CATEGORY.js`.

The easiest way to enable committing is probably to setup a webdav with Apache.

The following steps explain how to setup a webdav for Amber with Debian, but the setup on OSX and other Linux distros should be similar.

#### Installing Apache and enabling the dav module

Evaluate the following as root:

    ~# apt-get install apache2
    ~# a2enmod dav
    ~# a2enmod dav_fs

#### Creating a password for the webdav

    ~# htpasswd -c /etc/apache2/htpasswd-webdav USERNAME

#### Setting up the webdav directory

Add the following lines to the default vhost (in `/etc/apache2/sites-available/default`):

    Alias /amber/ "/path/to/amber/"
    <Directory "/path/to/amber/">
          Options Indexes MultiViews FollowSymLinks
          DirectoryIndex index.html
          AllowOverride None
          Order allow,deny
          allow from all

          Dav on

          AuthType Basic
          AuthName "amber"
          AuthUserFile /etc/apache2/htpasswd-webdav
          <LimitExcept GET OPTIONS>
                Require valid-user
          </LimitExcept>

    </Directory>

Make sure the group `www-data` has required rights to make changes to files in the webdav directory.

#### Restarting Apache

To restart Apache, evaluate the following:

    ~# /etc/init.d/apache2 restart

and go to `http://localhost/amber/`.

The class browser should now be able to commit changes to disk.

## The counter example

The following example is the traditional Seaside-like multi-counter application. The buttons at the bottom of each counter increase or decrease the counter.

Open a
on the `Counter` class in the `Canvas` class category.

Each Amber widget is a subclass of `Widget`. A widget is a graphical component. The `#renderOn:` method is used to generate HTML usinng the HTML canvas.

Rendering methods should be placed in the `rendering` method protocol, and action methods in the `actions` protocol.

{% highlight smalltalk %}renderOn: html html h1 with: count asString. html button with: '++'; onClick: [self increase]. html button with: '--'; onClick: [self decrease] {% endhighlight %}

## The HTML canvas

Amber allows developers to write HTML with a Canvas API similar to Seaside. The explanations below won't be really interesting to seasiders, there are however a few differences with the API Seaside provides.

Each HTML tag is represented by an instance of `TagBrush`, used to paint the tag on a `HTMLCanvas`. The `HTMLCanvas>>tag:` method adds a tag brush to the canvas object. For convenience, the `tags` method protocol includes methods for easily adding tag brushes named after each selector name:

{% highlight smalltalk %}| html | html := HTMLCanvas new. html p with: 'This is a paragraph with a link to '; with: [ html a href: 'http://www.google.fr'; with: 'Google'] {% endhighlight%}

You can
the `HTMLCanvas` class to get the list of all tag methods.

The `with:` method will call the polymorphic `appendToBrush:` method on the argument and allows you to add blocks, strings, tags, etc. to an existing tag brush or canvas.

`TagBrush` also has methods to bind events, like `#onClick:` or `#onChange:`, in the `events` protocol.

## Widgets

## jQuery

Amber comes with a jQuery binding. Each string or tag brush can be converted to a jQuery object, instance of the `JQuery` class in Amber, with `#asJQuery`.

{% highlight smalltalk %}'body' asJQuery. aTagBrush asJQuery.{% endhighlight %}

Once you get the jQuery object, you can use jQuery from Amber like you would do in JavaScript. JQuery methods in Amber follow the well documented jQuery API.

{% highlight smalltalk %}'body' asJQuery addClass: 'foo'; append: 'Hello world'; aTagBrush asJQuery hide.{% endhighlight %}

Once again, If you're looking for some particular method or want to learn more about how to use jQuery from Amber, you can
the `JQuery` class.