Skip to content
Wesley Yan Soares Brehmer edited this page May 19, 2024 · 15 revisions

Leahterfacee.js

Leatherfacee.js Documentation

Welcome to the official documentation for Leatherfacee.js, a lightweight JavaScript framework designed to provide a robust, modular, and easy-to-use structure for building front-end applications. This guide will help you understand the core features and how to use them effectively.

Table of Contents

  1. ChainsawAnim Class
  2. LefaceRender Class
  3. Component System
  4. Concurrent Mode
  5. Static Site Generator
  6. Directives
  7. Router
  8. Observer
  9. Services and Factories

ChainsawAnim Class

The ChainsawAnim class provides methods to create and manage CSS animations on DOM elements.

Methods

  • constructor(t): Initialize with a target element.
  • transform(t): Add a transformation to the list.
  • translate(x, y=0): Translate the element by x pixels horizontally and y pixels vertically.
  • rotate(deg): Rotate the element by deg degrees.
  • scale(x, y=x): Scale the element by x and y factors.
  • set(prop, value): Set a CSS property on the element.
  • duration(time): Set the duration of the animation.
  • end(callback): Apply the transformations and optionally execute a callback after the animation ends.
  • Timeout(config): Execute functions sequentially with a specified interval.
  • ATimeout(config): Execute functions with specified intervals for each.

Example

const anim = new ChainsawAnim('#myElement');
anim.translate(100, 50).rotate(45).scale(1.5).duration('1s').end(() => {
    console.log('Animation completed');
});

LefaceRender Class

The LefaceRender class is responsible for rendering templates and managing data reactivity.

Methods

  • constructor(options): Initialize with data, methods, target element, and template.
  • observe(data): Make data properties reactive.
  • compileTemplate(): Compile the template with data bindings.
  • render(): Render the compiled template to the target element.
  • bindDirectives(): Bind directives in the template.

Example

const renderer = new LefaceRender({
    data: { message: 'Hello, World!' },
    target: document.getElementById('app'),
    template: '<p>{{message}}</p>'
});

Component System

Leatherfacee.js supports a component-based architecture with support for computed properties and concurrent rendering.

LefaceComponent

Base class for all components.

LefaceComputedComponent

Extends LefaceComponent to support computed properties.

LefaceConcurrentComponent

Extends LefaceComputedComponent to support concurrent rendering.

Example

class MyComponent extends LefaceComponent {
    render() {
        this.element = document.createElement('div');
        this.element.innerText = this.props.text;
        document.body.appendChild(this.element);
    }
}

const leface = new Leface();
leface.register('MyComponent', MyComponent);
leface.create('MyComponent', { text: 'Hello, Leatherfacee!' });

Concurrent Mode

Enables concurrent rendering of components.

ConcurrentMode

  • enqueue(component): Enqueue a component for concurrent rendering.

Example

class MyConcurrentComponent extends LefaceConcurrentComponent {
    renderComponent(props) {
        const element = document.createElement('div');
        element.innerText = props.text;
        document.body.appendChild(element);
        return element;
    }
}

leface.register('MyConcurrentComponent', MyConcurrentComponent);
leface.create('MyConcurrentComponent', { text: 'Rendering concurrently!' });

Static Site Generator

Generate a static site from registered components.

StaticSiteGenerator

  • generate(): Generate static HTML files for all registered components and package them into a ZIP file. Requires JSZip

Example

leface.generateStaticSite();

Directives

Custom directives to extend HTML with custom behavior.

LefaceDirectives

  • register(name, hook): Register a new directive.
  • apply(element, props): Apply directives to an element.

Example

lefaceDirectives.register('my-directive', (element, value) => {
    element.innerText = value;
});

Router

Simple client-side router for single-page applications.

LefaceRouter

  • registerRoute(path, component): Register a route with a component.
  • navigateTo(path): Navigate to a registered route.

Example

const router = new LefaceRouter();
router.registerRoute('/home', MyComponent);
router.navigateTo('/home');

Observer

Observe changes to component properties and re-render components.

LefaceObserver

  • observe(instance): Observe properties of an instance.
  • setProp(obj, prop, value): Set a property value and notify observers.

Example

const observer = new LefaceObserver();
observer.observe(myComponentInstance);
observer.setProp(myComponentInstance.props, 'text', 'Updated text!');

Services and Factories

Provide a way to manage dependencies and create instances of objects.

LefaceService

  • register(name, service): Register a service.
  • get(name): Retrieve a registered service.

LefaceFactory

  • register(name, factory): Register a factory function.
  • create(name, ...args): Create an instance using a factory function.

Example

lefaceService.register('myService', new MyService());
const myService = lefaceService.get('myService');

lefaceFactory.register('myFactory', (arg1, arg2) => new MyClass(arg1, arg2));
const myInstance = lefaceFactory.create('myFactory', 'arg1', 'arg2');

LefaceCrossPlatform

Purpose

The primary objective of the LefaceCrossPlatform function is to simplify the process of delivering customized stylesheets tailored to specific device platforms. By detecting the user's device characteristics, such as screen size and platform type, it ensures an optimized browsing experience across different devices.

Function Signature

LefaceCrossPlatform(styles)

Parameters

  • styles (object): An object containing key-value pairs where the keys represent different device platforms (e.g., "Desktop", "Mobile", "Tablet") and the values specify the corresponding CSS file paths.

Usage

To utilize the LefaceCrossPlatform function effectively, follow these steps:

  1. Include the Function: Ensure that the LefaceCrossPlatform function is accessible within your JavaScript environment. You can either define it inline or include it from an external script file.

  2. Call the Function: Invoke the LefaceCrossPlatform function within your code, passing an object containing CSS file paths mapped to specific device platforms as an argument.

  3. Define CSS Paths: Provide CSS file paths for each targeted platform. These paths should point to the respective CSS files containing the styles intended for desktops, mobile devices, and tablets.

  4. Implementation: Integrate the LefaceCrossPlatform function call into your web application's initialization code, typically within the window.onload event handler or at an appropriate initialization phase.

Examples

Basic Usage

LefaceCrossPlatform({
    "Desktop": "styles/desktop.css",
    "Mobile": "styles/mobile.css",
    "Tablet": "styles/tablet.css"
});

In this example, the function is configured to load different CSS files based on the user's device platform. For desktops, it loads "desktop.css," for mobile devices, it loads "mobile.css," and for tablets, it loads "tablet.css."

Optional Tablet CSS

LefaceCrossPlatform({
    "Desktop": "styles/desktop.css",
    "Mobile": "styles/mobile.css"
});

If tablet-specific styles are not provided, the function gracefully handles the absence of the "Tablet" key, ensuring compatibility with a wide range of configurations.

LefaceUtils

// Loading external CSS
LefaceUtils.loadExternalCSS('https://example.com/styles.css');

// Loading an external JS
LefaceUtils.loadExternalJS('https://example.com/script.js').then(() => {
    console.log('Script loaded!');
}).catch((error) => {
    console.error('FATAL ERROR:', error);
});

// Insert HTML
LefaceUtils.insertHTML('#myElement', '<p>Inserted content</p>');

// Modifying an element's attributes
LefaceUtils.setElementAttribute('#myElement', 'data-test', 'valor');

// Switching the visibility of an element
LefaceUtils.toggleVisibility('#myElement');

// Sanitize HTML
const sanitizedHTML = LefaceUtils.sanitizeHTML('<p onclick="alert(1)">Text</p>');
console.log(sanitizedHTML);

LefaceRequests

Basic Usage

GET Requests

To make a GET request, you need to provide the URL of the resource you want to access and a callback function to handle the response.

LefaceRequests.get('https://api.example.com/data', function(response) {
    console.log(response); // Here you can process the response
});

POST Requests

To make a POST request, in addition to the URL, you need to provide the data to be sent as a JavaScript object and a callback function to handle the response.

var data = { name: 'John', age: 25, city: 'New York' };
LefaceRequests.post('https://api.example.com/submit', data, function(response) {
    console.log(response); // Here you can process the response
});

More Details

Error Handling

LefaceRequests automatically handles network errors, such as connection failures or unexpected server responses. You can add error handlers to your callback function to deal with these situations.

LefaceRequests.get('https://api.example.com/data', function(response) {
    console.log(response);
}, function(error) {
    console.error('An error occurred:', error);
});

Sending Custom Headers

You can send custom headers with your requests, such as authorization or content headers. Simply add an object containing the desired headers as the last parameter.

var headers = { 'Authorization': 'Bearer token123' };
LefaceRequests.get('https://api.example.com/data', function(response) {
    console.log(response);
}, null, headers);

Examples

  • GET Request: Fetching weather data from a weather API.
LefaceRequests.get('https://api.weatherapi.com/forecast.json?key=YOUR_API_KEY&q=London', function(response) {
    console.log(response);
});
  • POST Request: Sending form data to the server.
var data = { name: 'Maria', age: 30, city: 'Rio de Janeiro' };
LefaceRequests.post('https://api.example.com/submit', data, function(response) {
    console.log(response);
});
  • GENERAL EXAMPLE:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/gh/simplyYan/lympleRequest@main/lymple.js"></script>
</head>
<body>
    <input type="text" name="nome" id="nome" placeholder="Type yout name">
    <button onclick="send()">Send</button>
    <script>
        function send() {
            var nome = document.getElementById("nome").value;
            var data = { name: nome }

            LefaceRequests.post('index.php', data, function(response) {
                console.log(data)
                console.log(response);
            }, { 'Content-Type': 'application/json' });
        }
    </script>
</body>
</html>
<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    $data = json_decode(file_get_contents("php://input"), true);

    if (isset($data['name'])) {

        $name = $data['name'];

        echo "The name sent is: " . $name;
    } else {

        http_response_code(400);
        echo "The 'name' field was not found in the data.";
    }
} else {

    http_response_code(405);
    echo "Method not allowed. Only POST requests are accepted.";
}
?>

LefaceValidator

const isRequired = (value) => value ? null : 'This field is required.';
const isEmail = (value) => /\S+@\S+\.\S+/.test(value) ? null : 'This field must be a valid email address.';
const minLength = (length) => (value) => value.length >= length ? null : `This field must be at least ${length} characters long.`;

// Example
document.addEventListener('DOMContentLoaded', () => {
    const form = document.querySelector('#myForm');
    const validator = new LefaceValidator(form);

    validator.addValidation('username', [isRequired, minLength(5)]);
    validator.addValidation('email', [isRequired, isEmail]);

    form.addEventListener('submit', (event) => {
        event.preventDefault();
        if (validator.validate()) {
            alert('Form is valid!');
        } else {
            alert('Please correct the errors in the form.');
        }
    });
});

Leatherlang

Leatherlang is a simple markup language for building interfaces in a simple way. It is already included in Leatherfacee, and you can use it at any time. Leatherlang lets you only react to clicks. Hover effects can usually be achieved in CSS and other events are simply out of the scope of this language. By keeping its feature set light and focused, uilang aims to lower the barriers to entry into programming. Here's an example of the Leatherlang language:

when click on "h4" removes class "active" on "h4.active"
when click on "h1" removes class "open" on "h1.open"
when click on ".rsvp" adds class "open" on "#overlay"
when click on ".close, .confirm" removes class "open" on "#overlay"
  • Here's a complete real-life example:
<!doctype html>
<meta charset=utf-8>
<title>Example</title>
<head>
    <link rel=stylesheet href="style.css">
</head>
<body>
    
<div id=notification>
  <p>You have 3 unread messages.</p>
  <button class=hide>Hide</button>
</div>

<script src="leatherfacee.js"></script>

<script>
    const lelang = new Leatherlang();
    lelang.Code('when click on ".hide" adds class "hidden" on "#notification"');
</script>
</body>
</html>

Leatherlang is inspired by uilang, but with several differences such as semantics and integration, which works directly in JavaScript. To use Leatherlang, all you need is Leatherfacee. Whenever you want to use Leatherlang code, you just need to create a Leatherlang instance and use the Code function, as in the code below:

const lelang = new Leatherlang();
lelang.Code('when click on ".hide" adds class "hidden" on "#notification"');

Remember that you can name the instance whatever you want, the name “lelang” was chosen because it is short and an abbreviation, but you can use any name. And obviously, you can use multiple lines to write your Leatherlang code, see:

const lelang = new Leatherlang();
lelang.Code(`
clicking on "h1" removes class "open" on "h1.open"
clicking on "h1" adds class "open" on "target"
`);
Clone this wiki locally