Code Monkey home page Code Monkey logo

nutmeg-core's Introduction

Nutmeg

Try it in the Live Editor

A 1:1 mapping of HTML code to JavaScript functions.
All Nutmeg code is client-side JavaScript.
For an example of Nutmeg in action, see my personal site: owen.cafe.

It is now recommended to use Nutmeg-Router for building your Nutmeg projects.

Table of Contents

Why

  • Functions are neater than xml-esque code
  • Avoid code repetition
  • Better abstraction
  • Improve maintainability
  • Reduce code size
  • Reduce bandwidth usage
  • Reduce load time

What's wrong with this other thing I use?

  • Pre-processors:
    • Produce large amounts of code
  • The big guys (React / Angular / Other)
    • Try to do too many things
    • Are massive libraries/frameworks
    • Dictate code style / data flow

What does it look like?

Structure

Nutmeg's goal is to have the cleanest syntax possible, as such, Nutmeg has no
closing tags. Every element is a JavaScript function.

body(
    div(
        h1('Nutmeg'),
        'Hello World',
        div(
            div(
                "Don't disturb my nest!",
                br(),
                "Thanks.",
                br(),
                a('Take me to the Nutmeg repo').href('https://github.com/414owen/Nutmeg')
            )
        )
    )
)

However, the basic structure of HTML is maintained. Elements enclose other
elements.

Modifiers

Modifiers change a Nutmeg element, then return the element. This allows us to
chain modifiers together very neatly. There are modifiers for changing
attributes and properties of elements. We have already seen a modifier above.

var result = div();

...

form(
    result,
    input()
        .placeholder('Type here')
        .onkeyup(function(e) {
            result.clear()(e.target.value)
        }),
    button('Submit').onclick(console.log)
)

There is a shortcut to calling modifiers, which doesn't involve creating the
element explicitly first.

// create input, then apply modifier
input().placeholder('hello')

// is the exact same as
input.placeholder('hello')

Also, as the modifiers return a Nutmeg element, we can call the modified element
to add children. This allows modifiers to be used before and after adding
children.

// create element with children
div(
    'The answer is: ',
    42
).style({fontSize: '42px'})

// is the exact same as
div.style({fontSize: '42px'})(
    'The answer is: ',
    42
)

// is the exact same as
div('The answer is: ')
    .style({fontSize: '42px'})(42)

Style

As seen above, styles can be applied directly using object literals. For a
better system, involving dependency management, pseudo-elements and all sorts
of fun, we create a style object with mergeStyle().

var style = mergeStyle({
    base: {
        backgroundColor: '#ccc',
        fontSize: '20px'
    },
    bordered: {
        borderRadius: '8px',
        border: '1px solid #111'
    },
    example: {
        depends: ['bordered', 'base'],
        padding: '20px'
    }
});

This structure, on its own, does nothing. We would apply it to an element with
the .style modifier, for example:

div.style(style.example)('Hello World')

With regards to dependencies, you can have as many as you want, and they will
be applied in the order they are declared, so you can overwrite styles from
your dependencies easily.

Your dependencies can of course have dependencies, and all styles are resolved
by mergeStyle with a depth first search.

Repetition

Nutmeg parameters can be other Nutmeg elements, anything that can be stringified
(eg. numbers), or array-like objects of these. To show this, we will generate an
array of the first 500 fibonacci numbers, and append it to body.

// Generate an array of the first 500 fibonacci numbers
var curr = 1;
var prev = 0;
var fibs = Array.apply(0, Array(500)).map(
    function (fib, ind) {
        var oldc = curr, oldp = prev;
        curr += prev;
        prev = oldc;
        return oldp;
    }
);

// body is taking an array of Nutmeg elements
body(
    fibs.map(function(fib) {
        // div is taking a number
        return div(fib).style({margin: '20px'});
    })
);

Getting set up

  • Create your html page
  • Include the Nutmeg library using a script tag or otherwise
  • Paste this into your JavaScript file:
window.onload = function() {

    // Declare all Nutmeg functions locally
	eval(Nutmeg.localScope);

    // * Insert your Nutmeg code here *
}
  • Write some code

You can of course use your own way of running code when the document is ready,
and you don't have to declare Nutmeg functions locally, you can do something
like:

var n = Nutmeg;
n.body(
    'Hello World',
    n.br(),
    n.input.type('file')
)

nutmeg-core's People

Contributors

414owen avatar datkinson avatar zantier avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

datkinson

nutmeg-core's Issues

text() should not be necessary

We should check if an argument to an elified is text.

Current Syntax:

h1(
    text('Hello World')
)

Proposed Syntax:

h1(
    'Hello World'
)

Add canvas support

Need a way of getting a canvas element, with correct settings for hiDPI, and getting a context.

Support pseudo-elements

Support pseudo-elements in style engine.
Should be able to simulate them all with Javascript, onmouseover() and onmouseout() for hover, that sort of thing.

Proposed Syntax:

mystyle: {
    color: '#ddf',
    hover: {
        color: '#fdd'
    }
}

Add all the possible attributes to elified

I think we can loop over all the properties in an element, and create functions in elified that assign to them, before setting our custom ones.

for (var propName in elem) {
   elified.propName = function(val) {elem.propName = val;};
}

I just don't have time to experiment with it right now, so @Zantier if you want something to do today?

It might impact performance a bit, maybe run a profile on example.html before and after?

Closure compiler fails.

We need to add enough JSDoc blocks for closure to know what to do.
When we get it to the stage where it compiles, we can turn on advanced optimizations and es6 -> es5 transpilation. Should make the whole process a lot nicer.

Allow syntax div.style()

I'm not sure that this is worth the complication it will cause in the code.

Effectively, "div" itself needs to be elified, or at least have the same functions as an elified element, i.e. div.style, div.classes, etc. And the start of these functions need to actually construct a new elified div.

div().style(): Easy. A new div is created by div().

div.style(): The new div needs to be created (or retrieved, in the case of body) within style(). I imagine div will have a reference to a constructor of either div elements or elified div elements.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.