Skip to content

lino-smart/mini-framework

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mini-framework

Table of Contents

Overview

GEDOM is a framework-like tool that is meant to be used in any web application to simplify DOM Manipulation. It uses the concept of DOM Abstraction to create web components without having to use all those DOM methods.
It also uses a global State Management to have a control over every changes in the application.
It finally uses a Router to make sure the suitable components are rendered in the current adrress.
As an example, GEDOM will be use to create a basic TodoMVC web application.

Tech Stack

Languages

Click on badges to get to the code...

HTML5 CSS3 JAVASCRIPT

Development

WARP SHELL SCRIPT MARKDOWN

OS & Version Control

MAC OS GITHUB TRELLO

Installation

Cloning & Running

$ git clone http://learn.zone01dakar.sn/git/jefaye/mini-framework
$ cd mini-framework/
$ node src/server.js

File System

.
├── src
│   ├── components
│   │   ├── atoms
│   │   │   ├── atoms.md
│   │   │   ├── button.js
│   │   │   ├── clear-completed.js
│   │   │   ├── input.js
│   │   │   ├── label.js
│   │   │   ├── link.js
│   │   │   ├── text.js
│   │   │   └── todo-count.js
|   |   |
│   │   ├── molecules
│   │   │   ├── item.js
│   │   │   ├── molecules.md
│   │   │   └── todo-list.js
|   |   |
│   │   ├── organisms
│   │   │   ├── organisms.md
│   │   │   ├── todo-footer.js
│   │   │   ├── todo-header.js
│   │   │   └── todo-main.js
|   |   |
│   │   ├── pages
│   │   │   ├── error.js
│   │   │   └── pages.md
|   |   |
│   │   └── templates
│   │       ├── app-todo.js
│   │       ├── footer.js
│   │       └── templates.md
|   |
│   ├── core
│   │   ├── node.js
│   │   ├── router.js
│   │   └── state.js
|   |
│   ├── styles
│   │   ├── error.css
│   │   └── index.css
|   |
│   ├── app.js
│   ├── index.html
│   └── server.js
|
├── .gitignore
├── audit.todo
├── gitify.sh
├── LICENSE
└── README.md

9 directories, 32 files

Usage

The Virtual Node is a class that generates a component, given a 'properties' object as arguments.
Basically, the properties object would be in this configuration:

  const properties = {
    tag: /* HTML tag name (default: 'div') */ ,
    attrs: {
      // attribute: value
      // ...
    },
    listeners: {
      // event: callback function
      // ...
    },
    children: [
      // VirtualNode || Object || String
      // ...
    ]
  }

Calling the render() method on an instance of a Virtual Node will create the element through the tag field value, then set attributes and listeners, then add all given children of one of these types:

virtual node

  const TodoApp = new VirtualNode({
    tag: "section",
    attrs: {
      class: "todoapp",
    },
    children: [
      todoHeader,
      todoMain,
      todoFooter
    ],
  });

object

  class TodoHeader extends VirtualNode {
    constructor() {
      super({
        tag: "header",
        attrs: {
          class: "header",
        },
        children: [
          {
            tag: "h1",
            children: ["todos"],
          },
          {
            tag: "input",
            attrs: {
              class: "new-todo",
              placeholder: "What needs to be done?",
              autofocus: "",
            },
            listeners: {
              onchange: event => {
                if (event.target.value.trim() !== "") {
                  todoList.addTodo(event.target.value);
                  event.target.value = "";
                }
              },
            },
          },
        ],
      });
    }
  }

string

  export default new VirtualNode({
    tag: "footer",
    attrs: {
      class: "info",
    },
    children: [
      {
        tag: "p",
        children: [
          "Double-click to edit  a todo"
        ],
      },
      {
        tag: "p",
        children: [
          "Created by the Todo01   team"
        ],
      },
      {
        tag: "p",
        children: [
          "Part of ",
          new Link ("https://todomvc.com/", "TodoMVC")
        ],
      },
    ],
  });

Finally, the VirtualNode class will returns the created element that can now be append to any element of the DOM.

Additionally, the VirtualNode class has some interesting methods to:

Select an element from a virtual node's children using its index.

  select(index) {
      let child = this.children[index]

      if (!child) {
        return
      }

      if (!(child instanceof VirtualNode) && typeof child !== 'string') {
        child = new VirtualNode(child)
      }

      return child
  }

Add a node to the current node by appending its element to the current node's element or pushing its node to the current node's children.

  add(child) {
    if (!this.elem) {
      this.children.push(child);
      return
    }
    
    if (typeof child === 'string') {
      this.elem.textContent += child;
      return
    }
    
    if (!(child instanceof VirtualNode)) {
      child = new VirtualNode(child)
    }
            
    this.elem.appendChild(child.elem || child.render())
  }

Replace the node content by removing the entire content and append the given element using the add() method or reallocating the current node's children with the new children.

  replace(...children) {
    if (this.elem) {
      this.elem.innerHTML = '';
      children.forEach(child => this.add(child));
      return
    }
    
    this.children = [...newChild];
  }

The State of the application is set using an object that can contain any sort of data. The power of the state manager resides in the facts that it is the ONE source of truth for the entire application.
First, after being importing, the State class is initially set with all data of the application that can be changed by the components logic using the set() method.

  todoState.set({
    todos: [],
    filter: "all",
    counter: {
      active: 0,
      completed: 0,
    }
  });

The subscribe() method will basically add any funtion, method or callback that needs to update one or more elements of the application.

  todoState.subscribe(todoMain.display.bind(todoMain));
  todoState.subscribe(todoFooter.display.bind(todoFooter));
  todoState.subscribe(todoList.display.bind(todoList));
  todoState.subscribe(clearCompleted.display.bind(clearCompleted));
  todoState.subscribe(todoCount.refresh.bind(todoCount));

Instead of changing an element directly, the modifications will be done in the State.

    todoState.set({
      todos: todoState.current.todos.filter(todo => !todo.state.completed),
      counter: {
        ...todoState.current.counter,
        completed: 0,
      },
    });

The set() method contains a private method (#notify()) that will call all the subscribed functions, which will update all elements without needing to refresh the entire page/template.

  notify() {
    this.subscribers.forEach(callback => callback(this.current));
  }

Optionally, the set() method can take a callback as an argument for more complex operations.

The Router as the name implies is supposed to in conjunction with the State manager in order to determine which components will be rendered given the current URI of the address.
Once the router instance is created, the routes are registered using the add() method that takes the endpoint of the URL and the handler that basically apply the rendering of the allowed components.

  const router = new Router()
  router.add("/", () => {
    todoState.set({ filter: "all" });
  })

  router.add("/active", () => {
    todoState.set({ filter: "active" });
  });

  router.add("/completed", () => {
    todoState.set({ filter: "completed" });
  });

Whenever the address changes, the router get the resulting URL and change the state of the application so it can take care of the rest.
The URL is supposed to be a hash link so it won't redirect to a different page while avoiding page reload.

Aknowledgements

Contributors

fakeita aliouniang mamadbah jefaye

Peers

eibounda babacandiaye mbadiao

Testers

moustapndiaye mthiaw

Auditors

Sources

YOUTUBE MEDIUM

License

MIT License

About

Lightweight custom web framework for building scalable applications with modular architecture and clean design principles

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors