Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major refac #48

Merged
merged 4 commits into from
Dec 11, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ jobs:
prerelease: false

- name: Generate documentation
run: npm run generate-docs
run: npm run generate-docs || true

- name: nojekyll
run: touch docs/.nojekyll
113 changes: 41 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -18,7 +18,9 @@ domodel is front-end library that organizes the user interface into models (look

A model is a JSON representation of a DOM [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element).

Let's take this model for example:
A model can also be used to refer to both the [Model](https://domodel.unificator.me/module-core.html#~Model) and its [Binding](https://domodel.unificator.me/domodel/Binding.html) as a whole, that is a component (a search bar model for example).

Let's take this [Model](https://domodel.unificator.me/module-core.html#~Model) for example:

```javascript
export default {
@@ -32,7 +34,7 @@ That would the equivalent of:
const button = document.createElement("button")
```

A model with children:
Next, a [Model](https://domodel.unificator.me/module-core.html#~Model) with children:

```javascript
export default {
@@ -47,56 +49,30 @@ export default {
}
```

Notice the ``textContent`` property. You can set any [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) properties in this fashion.

The ``identifier`` property is a model property.

Note: The term model will later be used to refer to both the model and its [Binding](https://thoughtsunificator.github.io/domodel/Binding.html) to make it simpler.


You can also ommit the ``tagName`` and you will get a fragment document model:

```javascript
export default {
// Only the 'children' property is allowed when working with a DocumentFragment.
children: [
{
tagName: "h2",
identifier: "headline",
textContent: "Unveil a new world"
}
]
}
```
Notice the ``textContent`` property. You can set any [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) properties in this fashion.

That would the equivalent of:
> If you want to set an ``attribute`` use the attributes object property.

```javascript
const documentFragment = document.createDocumentFragment()
const h2 = document.createElement("h2")
// ...
documentFragment.appendChild(h2)
```
The ``identifier`` allows your binding to track a model and manipulate it in within the available hooks.

#### Properties
<a href="#model-properties"></a>

Most properties listed in your model are defined at the Element level.
Most properties listed in your model comes from the [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) class.

It also includes:

However custom properties are not set on the Element as they have unusual behaviors they are treated differently:
- ``tagName`` - ``string`` - Which is passed to ``createElement``
- ``children`` - ``Array`` - To add children to an Element
- ``identifier`` - ``string`` - To save and retrieve a Node
- ``childModel`` - [ChildModel](https://domodel.unificator.me/module-core.html#~ChildModel) - [For model nesting](#nesting-models)

- ``tagName`` - String - Passed to ``createElement``
- ``children`` - Array - To add children to an Element
- ``identifier`` - String - To save and retrieve a Node
- ``model`` - Model - Specify the model that should be ran
- ``binding`` - [Binding](http://domodel.unificator.me/Binding.html) - Specify the [Binding](http://domodel.unificator.me/Binding.html) to use when running the model (``model`` property must be set)
- ``properties`` - Object - Specify the arguments to pass along the [Binding](http://domodel.unificator.me/Binding.html) (``binding`` property must be set)

### Core

#### Adding models to the DOM and managing them

To add a model to the DOM we use the [Core.run](http://domodel.unificator.me/Core.html#.run) method provided by the DOModel module and tell it how to add them.
To add a [Model](https://domodel.unificator.me/module-core.html#~Model) to the DOM we use the [Core.run](http://domodel.unificator.me/Core.html#.run) method provided by the [Core module](http://domodel.unificator.me/Core.html).

Create a ``main.js`` in ``src/``, it is the entry point module that is defined in your ``index.html`` :

@@ -108,19 +84,17 @@ import { Core } from "domodel" // first we're importing DOModel
import Model from "./model/model.js" // the model we defined earlier, it is our super model
import ModelBinding from ".model/model.binding.js" // the binding we will be defining .bindinglater

window.addEventListener("load", function() { // we only add the
window.addEventListener("DOMContentLoaded", function() {
Core.run(Model, {
method: Core.METHOD.APPEND_CHILD, // This is the default method and will append the children to the given parentNode.
method: Core.METHOD.APPEND_CHILD, // This is the default method and will append the children to the given target.
binding: new ModelBinding({ myProp: "hello :)" }), // we're creating an instance of our binding (which extends the Binding class provided by DOModel) and passing it to the run method.
parentNode: document.body // the node we want to target in this case it is the node where we want to append the child node using appendChild.
target: document.body // the node we want to target in this case it is the node where we want to append the child node using appendChild.
})
})

```

The documentation for Core.run is available [here](https://domodel.unificator.me/Core.html#.run).

The associated [Binding](http://domodel.unificator.me/Binding.html):
Create the associated [Binding](http://domodel.unificator.me/Binding.html):

``src/model/model.binding.js``
```javascript
@@ -129,15 +103,12 @@ import { Core } from "domodel" // you could import the library again and run yet
class ModelBinding extends Binding {

onCreated() {
const { myProp } = this.properties

console.log(myProp) // prints hello

// access your model root element through the root property: this.root

// access identifier with the identifier property:

this.identifier.headline.textContent = "The new world was effectively unveiled before my very eyes"
this.elements.headline.textContent = "The new world was effectively unveiled before my very eyes"

// you might even run another model inside this model
}
@@ -149,23 +120,23 @@ export default ModelBinding

#### Methods

- ``APPEND_CHILD`` Append your model to ``parentNode``
- ``APPEND_CHILD`` Append your model to ``target``

- ``INSERT_BEFORE`` Insert your model before ``parentNode``
- ``INSERT_BEFORE`` Insert your model before ``target``

- ``INSERT_AFTER`` Insert your model after ``parentNode``
- ``INSERT_AFTER`` Insert your model after ``target``

- ``REPLACE_NODE`` Replace ``parentNode`` with your model
- ``REPLACE_NODE`` Replace ``target`` with your model

- ``WRAP_NODE`` Wrap ``parentNode`` inside your model
- ``WRAP_NODE`` Wrap ``target`` inside your model

- ``PREPEND`` Insert your model before the first child of ``parentNode``
- ``PREPEND`` Insert your model before the first child of ``target``

They are available through ``Core.METHOD``.
These are available through [Core.METHOD](https://domodel.unificator.me/module-core.html#~Method).

### Binding

Binding are the behavior part of our model it is required for any model to have a [Binding](http://domodel.unificator.me/Binding.html) with it.
While a [Model](https://domodel.unificator.me/module-core.html#~Model) defines the look of a component, a [Binding](http://domodel.unificator.me/Binding.html) defines its behavior.

#### Hooks

@@ -175,7 +146,7 @@ The following are hooks that your binding can implement to add specific behavior

This method will be called before your model is added to the DOM.

#### onRendered
#### onConnected

This method will be called immediately after your model is added to the DOM.

@@ -184,7 +155,6 @@ This method will be called immediately after your model is added to the DOM.

The following properties are made available from within the the instance of a [Binding](http://domodel.unificator.me/Binding.html):

- ``properties`` Properties passed along when instancing a binding.
- ``root`` Root [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) of your model.
- ``identifier`` Hosts individual [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) previously tagged in the definition of the model (see [Model properties](#model-properties)).

@@ -200,8 +170,7 @@ Listen to a given observable event. See [Binding.listen](https://domodel.unifica

Synonym of [Core.run](https://domodel.unificator.me/Core.html#.run), with the differences being :

- ```parentNode``` property is set to the current binding root element.
- All ```properties``` within Binding.properties are inherited by the child model.
- ```target``` property is set to the current binding root element.
- A hierarchy of models is created using Binding._children. Making it easier to remove them using [Binding.remove](https://domodel.unificator.me/Binding.html#remove).

#### remove
@@ -210,7 +179,7 @@ Remove the model from the DOM. See [Binding.remove](https://domodel.unificator.m

### Observable

An [Observable](http://domodel.unificator.me/observable.Observable.html) is a way for your models to communicate with each other.
An [Observable](http://domodel.unificator.me/observable.Observable.html) is a way for your models to communicate with each other and store their states.

``src/object/observable-example.js``
```javascript
@@ -233,7 +202,7 @@ export default ExampleObservable

##### EventListener

Here we associate the EventListener with our current binding and give it ``properties.observable`` as the observable to register the events to.
Here we associate the EventListener with our current binding and give it ``observable`` as the observable to register the events to.

``src/model/model.binding.js``
```javascript
@@ -243,8 +212,8 @@ import ModelEventListener from "/model/model.event.js"

class ModelBinding extends Binding {

constructor(properties) {
super(properties, new ModelEventListener(properties.observable))
constructor(observable) {
super(new ModelEventListener(observable))
}

}
@@ -325,7 +294,7 @@ import ModelBinding from "/model/model.binding.js"

const observable = new Observable()

Core.run(Model, { parentNode: document.body, binding: new ModelBinding({ observable }) })
Core.run(Model, { target: document.body, binding: new ModelBinding({ observable }) })


```
@@ -360,7 +329,7 @@ import ModelBinding from "./model.binding.js"
class extends Binding {

onCreated() {
Core.run(Model, { parentNode: this.root, binding: new ModelBinding() })
Core.run(Model, { target: this.root, binding: new ModelBinding() })
}

}
@@ -381,7 +350,7 @@ export default {
{
model: Model,
binding: ModelBinding // optionnal
properties: {} // optionnal
arguments: [] // optionnal
identifier: "model" // optionnal
// Any other property is not handled.
}
@@ -406,9 +375,7 @@ class extends Binding {

onCreated() {

console.log(this.identifier.model) // returns an instance of ModelBinding
// You could access the root element of the nested model through:
console.log(this.identifier.model.root)
console.log(this.identifiers.model) // returns an Identifier
// and much more...

}
@@ -433,10 +400,12 @@ const MyModel = {
]
}

const MyAlternative = new ModelChain(MyModel).after("title", {
const MyModelChain = new ModelChain(MyModel).after("title", {
tagName: "div",
textContent: "A description"
})

Core.run(MyModelChain.definition, { target: document.body })
```

Available methods:
3 changes: 1 addition & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export { default as Core } from "./src/core.js"
export * as Core from "./src/core.js"
export { default as Binding } from "./src/binding.js"
export { default as Observable } from "./src/observable.js"
export { default as Listener } from "./src/listener.js"
export { default as EventListener } from "./src/event-listener.js"
export { default as Model } from "./src/model.js"
export { default as ModelChain } from "./src/model-chain.js"
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "domodel",
"version": "1.1.10",
"version": "2.0.0",
"main": "index.js",
"type": "module",
"description": "Front-end library",
Loading