# Quickstart adon

- [adon Prerequisites](/eliosin/adon/prerequisites.html)
- [Installing adon](/eliosin/adon/installing.html)

## Previously on elioSin...

- Installed **god** ? [No](/eliosin/god/installing.html)
- You completed **god** Quickstart [No!](/eliosin/god/quickstart.html)
- You completed **eve** Quickstart [No!](/eliosin/eve/quickstart.html)
- **adon** understood [No!](/eliosin/adon)
- [Check the Demo](/eliosin/adon/demo.html)
- You previously created a new **elioSin** theme called `genesis`.
- You're currently running `gulp` in its root folder and can see the page.

## Nutshell

An adon adds and removes a class to a tagName based on simple user event. The name of the class should be camel formatted 'adon' + Name, e.g. `adonFullName`.

1. Create the file `js/adon/adonFullName.js`

2. Write your logic - basically like this, but cleverer:

```
// NB: Twinned with /stylesheets/adon/adonFullName.css
// NB: Tested by /test/adon/adonFullName.js
jQuery.fn.extend({
   adonFullName: function() {
       return $(this).toggleClass('adonFullName')
   }
});
```

1. Create the file `stylesheets/adon/adonFullName.scss`

2. Make the adonName the className in the scss, e.g.

```
adonFullName {
   // get sassy in here
}
```

1. Import the adonName into #{\$container} on `stylesheets/theme.scss`

2. Edit `js/main.js`

```
$(document).ready(function() {
   $('nav').adonFullName(true);
});
```

1. Ensure tagName is in the correct _prong_ in `stylesheets/settings.scss`

Do steps **1** to **6** in one go:

```
yo sin:adon
```

## Exercise 1 HideOnScrollDown An adon which hides tagNames when the page scrolls down

We're going to create an adon which can be used to hide things when the page is scrolling down. You can then add this adon on to any tagNames which you want to hide or show depending on the scrolling behaviour of the user.

Create and edit `js/adon/adonHideOnScrollDown.js`, adding this code:

```javascript
// NB: Twinned with /stylesheets/adon/adonHideOnScrollDown.scss
// NB: Tested by /test/adon/adonHideOnScrollDown.js
jQuery.fn.extend({
  adonHideOnScrollDown: function () {
    var tags = $(this)
    var position = $(window).scrollTop()
    $(window).scroll(function () {
      tags.each(function () {
        var tag = $(this)
        if ($(window).scrollTop() > position) {
          tag.addClass("adonHideOnScrollDown")
        } else {
          tag.removeClass("adonHideOnScrollDown")
        }
      })
      // reset the position after hiding all tags
      position = $(window).scrollTop()
    })
  },
})
```

While the page scrolls, all the tags connected to this adon will be given a new class `adonHideOnScrollDown`. When the page starts scrolling up, the class is removed.

### What we learnt

1. That the adon's javascript is adding and removing classes based on user interaction.

2. How to write an adon which responds to the window scrolling.

## Exercise 2 Styling adonName classes

Create and edit `stylesheets/adon/adonHideOnScrollDown.scss`, adding this code:

```scss
// DEBUG: Twinned with /js/adon/adonHideOnScrollDown.js
.adonHideOnScrollDown {
  transition: visibility 0s linear $transition, all 0s;
  transition-timing-function: ease;
  visibility: hidden;
}
```

As the page is scrolling, remember, all the tags connected to this adon will temporarily has the class name `adonHideOnScrollDown`. This short snippet of scss sets the `visibility: hidden;` of the `.adonHideOnScrollDown` style, with a transition effect timed by the `$transition` setting.

Finally, import `adon/adonHideOnScrollDown.scss` into `stylesheets/theme.js`:

```
  ...
  @import 'adon/adonHideOnScrollDown';
}
```

### What we learnt

1. A adon's functionality is handled using css.

2. There's nothing to stop you writing `$(this).hide()` in an adon, but the elioWay would be to have `visibility: hidden;` in the adon's activated class.

3. Apparently, there's a `$transition` setting!

## Exercise 3 Pluging in adons into tagNames.

To plug your adon into a tagName, simply add them as lines in your `js/main.js` file:

```javascript
// js/main.js
$(document).ready(function () {
  $("nav").adonHideOnScrollDown(true)
  $("blockquote").adonHideOnScrollDown(true)
})
```

This will attach your _adon_ to the tagNames `aside` and `blockquote`.

### What we learnt

1. How to plug an adon into a tagName.

## Exercise 4 FullScreenOnClick An adon which makes an tag full screen on click.

This time we will use **elioGod**'s **yeoman** generator, **generator-sin** by calling `yo sin:adon`. This will quickly scaffold all the files needed for your adon, including the beginnings of a test. Enter `FullScreenOnClick` as your adonName.

```shell
yo sin:adon
```

### What yo sin:adon makes

Respond to the questions, especially choosing an adonName.

This quickstart will assume you chose the name `FullScreenOnClick`.

What yeoman generator produces follows **adon**'s _pattern_ which is as follows:

```shell
project
│   ...
│
└───js
│   │   main.js
│   │   ...
│   │
│   └───adon
│       │   adonFullScreenOnClick.js
│       │   ...
│
└───stylesheets
│   │
│   └───adon
│       │   adonFullScreenOnClick.scss
│       │   ...
│
└───test
    │
    └───adon
        │-- adonFullScreenOnClick.js
        │   ...
```

### What we learnt

- `yo sin:adon` creates the `js/adon/adonName.js` script for your adonName.

- `yo sin:adon` creates `stylesheets/adon/adonName.scss` for styling a css class called `.adonName`.

- `yo sin:adon` creates `test/adon/adonName.js` for testing your adon.

- `yo sin:adon` adds `@import 'adon/adonName.scss';` to `stylesheets/theme.scss`.

## Exercise 5 adons are about style

Start off by deleting `js/adon/adonFullScreenOnClick.js`. We won't need it.

Instead we will use one I prepared earlier, `adonClick` which features in the [adonEvent](https://gitlab.com/eliosin/adon/blob/master/js/adon/adonEvent.js) jscript, provided in the **adon** package. In `@elioway/adon/js/adon/adonEvent.js` there are adons to toggleClass any given adonName in response to common event handlers. `adonClick` looks like this:

```javascript
// jQuery protoType
jQuery.fn.extend({
  //protoType method name + parameter
  adonClick: function (adonName) {
    // The protoType is attached to a selector...
    return $(this).each(function () {
      // ... but we want to handle each tag.click event independently
      var tag = $(this)
      // Toggle the class when the tag is clicked.
      tag.click(function () {
        tag.toggleClass(adonName)
      })
    })
  },
})
```

We just need include the `adonClick` adon to our gulp build.

Open the `gulpfile.js`.

Add the path to the package to the js_watch list:

```javascript
var js_watch = [
  "js/plugins.js",
  "js/adon/adon*.js",
  "./node_modules/@elioway/adon/js/adon/adonEvent.js",
]
```

Then add `$('article').adonClick('adonFullScreenOnClick')` the `js/main.js` file like this:

```
$(document).ready(function() {
  ...
  $('article').adonClick('adonFullScreenOnClick')
})
```

Now edit `stylesheets/adon/adonFullScreenOnClick.scss`:

```
.adonFullScreenOnClick {
  left: $personal-space;
  margin: 0 !important;
  position: absolute;
  right: $personal-space;
  z-index: 6000;
}
```

### What we learnt

1. The scss file is the most important feature of an adon. You might not even need the js.

2. How to write an adon without an adonName script file.

## Exercise 6 Testing your adon

Type `npm run prettier` at the command line. We expect 1 test to fail. This is the test yo sin:adon created in a previous execise.

You'll see something like this:

```shell
5 passing (61ms)
1 failing

1) jQuery.fn.extend.adonFullScreenOnClick
     removes class adonFullScreenOnClick from tag:
   TypeError: $(...).adofFullScreenOnClick is not a function
    at Context.done (test/adon/adonFullScreenOnClick.js:26:17)
    at Context.done (test/suites/adonTesterSuite.js:20:7)
```

The error 'TypeError: \$(...).adofFullScreenOnClick is not a function' happens because we deleted the jscript file.

This is how we fix that test. Open `test/adon/adonFullScreenOnClick.js`.

### Use an adon from the adon package

Change the line:

```
'../../js/adon/adonFullScreenOnClick.js',
```

to

```
'./node_modules/@elioway/adon/js/adon/adonEvent.js',
```

Whereever you see `$(testTag).adonFullScreenOnClick();` change it to the same statement for activating it which we added to the `js/main.js` in the previous exercise.

`$(testTag).adonClick('adonFullScreenOnClick');`

Remove the following two lines:

```
$(testTag).adofFullScreenOnClick();
$(testTag)[0].should.not.have.class('adonFullScreenOnClick'); // no class
```

Now you should have this:

```
const suites = require('../suites/adonTesterSuite');

var testTag = 'h1'
var testML = `<${testTag}>PRETEST</${testTag}>`

suites.AdonTesterSuite(
  'jQuery.fn.extend.adonFullScreenOnClick',
  '../../js/adon/adonFullScreenOnClick.js',
  testML,
  function() {
    it('adonFullScreenOnClick adds class to tag', done => {
      $(testTag)[0].should.not.have.class('adonFullScreenOnClick');
      $(testTag).adonClick('adonFullScreenOnClick');
      $(testTag)[0].should.have.class('adonFullScreenOnClick'); // true class
      done();
    });

    it('adofFullScreenOnClick removes class from tag', done => {
      $(testTag).adonClick('adonFullScreenOnClick');
      $(testTag)[0].should.have.class('adonFullScreenOnClick');
      done();
    });
  }
);
```

Run `mocha test/adon/adonFullScreenOnClick.js`. The tests pass, but the testing isn't complete. We need to make sure the adon responds to the click event.

In the following code, we test the h1 tag in our test HTML; simulating a click event using jQuery code.

```
const suites = require('../suites/adonTesterSuite');

var testTag = 'h1'
var testML = `<${testTag}>PRETEST</${testTag}>`

suites.AdonTesterSuite(
  'jQuery.fn.extend.adonFullScreenOnClick',
  './node_modules/@elioway/adon/js/adon/adonEvent.js',
  testML,
  function() {
    it('has no class when activated', done => {
      $(testTag)[0].should.not.have.class('adonFullScreenOnClick');
      $(testTag).adonClick('adonFullScreenOnClick');
      $(testTag)[0].should.not.have.class('adonFullScreenOnClick'); // until clicked
      done();
    });

    it('if adon is not activated, click has no effect', done => {
      $(testTag)[0].should.not.have.class('adonFullScreenOnClick');
      $(testTag).click();
      $(testTag)[0].should.not.have.class('adonFullScreenOnClick'); // until activated
      done();
    });

    it('if adon is activated, click toggles the class adonFullScreenOnClick', done => {
      $(testTag)[0].should.not.have.class('adonFullScreenOnClick');
      $(testTag).adonClick('adonFullScreenOnClick');
      $(testTag).click();
      $(testTag)[0].should.have.class('adonFullScreenOnClick'); // when clicked
      $(testTag).click();
      $(testTag)[0].should.not.have.class('adonFullScreenOnClick'); // toggled when clicked
      done();
    });
  }
);
```

Now run the test again using `npm run prettier`.

``

### What we learnt

1. How to write a test for our adon which handles user interaction.

## Tidy up

- Press `CTRL` and `C` to stop the browser.

- Type `npm run prettier` to make your work `prettier`.

- Type `npm run prettier`.

## Next

Now you have seen how to write adons for your elioSin themes. This completes the **elioSin** quickstarts.

Go into the world and preach the gospel!
