Giter Site home page Giter Site logo

imba / imba Goto Github PK

View Code? Open in Web Editor NEW
6.2K 107.0 170.0 27.12 MB

๐Ÿค The friendly full-stack language

Home Page: https://imba.io

License: MIT License

JavaScript 49.81% TypeScript 9.52% CSS 0.91% HTML 0.50% Shell 0.01% Imba 39.26%
programming-language javascript imba dom frontend declarative framework ui

imba's Introduction

Imba

Imba is a friendly full-stack programming language for the web that compiles to performant JavaScript. It has language-level support for defining, extending, subclassing, instantiating and rendering DOM nodes.

Get started

Try Imba instantly in your browser with our playground, or create a new project with:

npx imba create

Documentation

To get started with Imba, we recommend reading through the official guide.

Why Imba?

Minimal syntax

Imba's syntax is minimal, beautiful, and packed with clever features. It combines logic, markup and styling in a powerful way. Fewer keystrokes and less switching files mean you'll be able to build things fast.

import './util/reset.css'

global css html,body m:0 p:0 w:100% h:100%

tag login-form < form

	css input rd:md bc:gray3 h:20px fs:md
	css button rd:md c:white bg:gray4 @hover:blue4

	<self @submit.prevent=api.login(name,secret)>
		<input.username type='text' bind=name>
		<input.password type='password' bind=secret>
		<button> "Login as {name}"

imba.mount <login-form[pos:abs d:grid ja:center]>

Runs on both server and client

Imba powers both the frontend and the backend of Scrimba.com, our learning platform with 100K+ monthly active users. On the frontend, Imba replaces e.g., Vue or React, and on the backend, it works with the Node ecosystem (e.g., npm).

import express from 'express'
import services from './services.ts'
import html from './index.html'
import image from './confused-cat.png'

const app = express!

app.get '/404' do (req,res)
	res.send String <html> <body>
		<img src=image>
		<h1> "We could not find this page!"

app.get '/' do (req,res)
	res.send html.body

Integrated styling

Inspired by Tailwind, Imba brings styles directly into your code. Styles can be scoped to files, components, and even parts of your tag trees. Style modifiers like @hover, @lg, @landscape and @dark can be used for extremely concise yet powerful styling.

# global styles
global css button
	position: relative
	display: block
	background: #b2f5ea
	@hover background: #b2f9ea

# tailwind-inspired shorthands
global css button
	pos:relative d:block bg:blue5 bg@hover:blue6

tag App
	# scoped styles
	css item bg:blue4 m:2

	<self[d:grid pos:relative]> # inline styles
		<ul> for {type,title} in items
			<li.item is-{type}> title

Blazing fast, Zero config

Imba comes with a built-in bundler based on the blazing fast esbuild. Import stylesheets, images, typescript, html, workers and more without any configuration. Bundling is so fast that there is no difference between production and development mode - it all happens on-demand.

# importing a worker
const worker = import.worker './analyzer'
const analyzer = new Worker(worker.url)
# import an image
const logo = import './images/logo.png'
console.log "logo size: {logo.width}x{logo.height} - at {logo.url}"

When you run your app with the imba command, it automatically bundles and compiles your imba code, along with typescript, css and many other file types. It provides automatic reloading of both the server and client.

Typing and tooling

The tooling is implemented as a typescript server plugin giving us great intellisense, diagnostics, and even cross-file refactorings that works with js/ts files in the same project. You can import types just like in typescript, and annotate variables, parameters and expressions. Like the language, the tooling is still in alpha, but improving every day.

import type { CookieOptions } from 'express-serve-static-core'

def flash res\Response, body\string, settings = {}
	let options\CookieOptions = {
		...settings
		maxAge: 86400
		secure: true
		httpOnly: false
	}

	res.cookie('flash',body,options)

Community

For questions and support, please use our community chat on Discord.

License

MIT

Copyright (c) 2015-present, Sindre Aarsaether

imba's People

Contributors

aalemayhu avatar allain avatar andregoldstein avatar cfuendev avatar codeluggage avatar ericvida avatar familyfriendlymikey avatar gavinray97 avatar gdamjan avatar gitter-badger avatar haikyuu avatar illogikal avatar isaksundesingh avatar ismail-codar avatar joe-chelladurai avatar joserochadocarmo avatar judofyr avatar kaanrkaraman avatar koolamusic avatar lukeed avatar madmaniak avatar mpeg avatar pistus avatar russ avatar shreeve avatar sleewoo avatar somebee avatar taw avatar unplugandplay avatar vladdoster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imba's Issues

Make tag definitions closer to class definitions

The proposal here is to make tag definitions with a capital name behave more like classes. For instance:

tag Note
  def render
    <self> โ€ฆ

# is just sugar for
class Note < Element
  def render
    <self> โ€ฆ

This would then be local to the current file (or you could annotate it with export or global as with regular classes). The tag usage would then be a plain constructor:

<Note title="Hello" />
# compiles to:
(new Note).setTitle("Hello").end()

Lowercase tag names would still be global (as they are today) and should be used sparingly.

Note that this is very similar to how React works: https://babeljs.io/repl/#?experimental=true&evaluate=false&loose=false&spec=true&code=%3CDiv%20%2F%3E%3B%0A%3Cdiv%20%2F%3E%3B.

Remove chokidar dependency

Chokidar is currently used by the CLI for watching files. We use it in a very basic manner, and it should be easy enough to roll our own. That will get rid of quite a few dependencies, including fsevents, which is the only binary / compiled dep right now. We do have a longterm goal of removing all dependencies, and chokidar is the most important to start with. The other two (chalk and commander) can be phased out later.

`do` scope

First of all thanks for new hope.

And i'd like to contribute my two cents regard do generated functions scope...
I know there is self, but also there are scenarios when self does not help.

For example i'm requiring a set of functions from another file and injecting them into prototype:

module.exports =
  save: do |data|
    post data, do |response|

and compiled code looks like:

(function(){
  var self = this;

  return module.exports = {
     save: function(data) {

so save function's self is Window,
though this is still correct cause it was inserted into base class's prototype,
so if do would behave like fat arrow this would make the deal...

There are of course "brute force" solutions like

var fn = do
  some code
post data, fn.bind(this)

or even

post data, _:bind({ |response|
  some code
}, this)

but as you can see they are just dirty hacks for such a elegant language.

So if do and { } will behave like fat arrow we will have two ways to define functions:

  • def will define regular functions bound to self
  • do and {} will define scoped functions bound to this

makes sense?

thank you.

Worrying output on install

Hey guys. I decided after the hacker news exchange to take a deeper look. And make note of things I found worrisome or might be improved. So, here goes.

$ npm install -g imba

> [email protected] install /usr/local/lib/node_modules/imba/node_modules/chokidar/node_modules/fsevents
> node-gyp rebuild

  SOLINK_MODULE(target) Release/.node
  SOLINK_MODULE(target) Release/.node: Finished
  CXX(target) Release/obj.target/fse/fsevents.o
  SOLINK_MODULE(target) Release/fse.node
  SOLINK_MODULE(target) Release/fse.node: Finished
/usr/local/bin/imba -> /usr/local/lib/node_modules/imba/bin/imba
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/cookie-parser requires cookie@'0.1.2' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/cookie,
npm WARN unmet dependency which is version 0.0.5
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/cookie-parser requires cookie-signature@'1.0.5' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/cookie-signature,
npm WARN unmet dependency which is version 0.0.1
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/finalhandler requires debug@'~2.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/debug,
npm WARN unmet dependency which is version 0.7.2
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/method-override requires debug@'~2.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/debug,
npm WARN unmet dependency which is version 0.7.2
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/method-override requires methods@'1.1.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/methods,
npm WARN unmet dependency which is version 0.0.1
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/connect-timeout requires debug@'~2.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/debug,
npm WARN unmet dependency which is version 0.7.2
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/serve-favicon requires fresh@'0.2.4' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/fresh,
npm WARN unmet dependency which is version 0.1.0
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/serve-static requires send@'0.9.3' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/send,
npm WARN unmet dependency which is version 0.1.0
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/body-parser requires bytes@'1.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/bytes,
npm WARN unmet dependency which is version 0.1.0
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/body-parser requires qs@'2.2.4' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/qs,
npm WARN unmet dependency which is version 0.5.1
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/compression requires bytes@'1.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/bytes,
npm WARN unmet dependency which is version 0.1.0
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/compression requires debug@'~2.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/debug,
npm WARN unmet dependency which is version 0.7.2
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/express-session requires cookie@'0.1.2' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/cookie,
npm WARN unmet dependency which is version 0.0.5
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/express-session requires cookie-signature@'1.0.5' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/cookie-signature,
npm WARN unmet dependency which is version 0.0.1
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/express-session requires debug@'~2.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/debug,
npm WARN unmet dependency which is version 0.7.2
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/serve-index requires debug@'~2.0.0' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/debug,
npm WARN unmet dependency which is version 0.7.2
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/csurf requires cookie@'0.1.2' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/cookie,
npm WARN unmet dependency which is version 0.0.5
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/csurf requires cookie-signature@'1.0.5' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/cookie-signature,
npm WARN unmet dependency which is version 0.0.1
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/body-parser/node_modules/raw-body requires bytes@'1' but will load
npm WARN unmet dependency /usr/local/lib/node_modules/testem/node_modules/express/node_modules/connect/node_modules/bytes,
npm WARN unmet dependency which is version 0.1.0
[email protected] /usr/local/lib/node_modules/imba
โ”œโ”€โ”€ [email protected] ([email protected])
โ”œโ”€โ”€ [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected])
โ””โ”€โ”€ [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected])

You will notice all the "WARN" lines, which I find off-putting and scary.

(Thinking this may be because of an outdated nodejs installation, I proceeded to brew update but no, that didn't change anything.)

Replacing content of element

All the examples seem to append by doing e.g. $$(#app).append <todolist>.

I can't seem to find any reference in the ElementTag to a function that would replace the content. Am I missing it or could this be something that that could be added?

Could be nice for e.g. placeholders.

<div id="app">Loading...</div>

and then e.g. like in jQuery:

$$(#app).html <todolist>

Add tag hooks for mount / unmount

We need something like willMount, didMount, willUnmount (see lifecycle methods in react). Hooks should be called when the node is actually mounted in the document (not when it is appended to a parent).

There are a few different ways to implement it. Performance is a primary concern. Since almost all tags will not have such hooks I think we should look for them in defineTag/extendTag and then add some custom logic / override certain methods if present. More specific implementation ideas will be posted here.

Predeclare underscore (_) globally by default

Lots of people are using lodash/underscore. By default, imba predeclares quite a few global variables (console, process, window, setTimeout, ...) I think we should also predeclare '_' the same way.

This way users won't struggle with this, and there will be no need for adding extern _ to the top of every file that use it.

Support stdin and stdout in CLI

The compiler should support compiling code that does not reside in a file, and support outputting directly to stdout instead of to a file on disk.

Allow calling regular methods inside < tag >

@judofyr and I have discussed another syntax addition related to tags. I've often wanted to set something like a css property inside my rendering. Imagine a render method that now looks like this:

def render
    <self>
        <div@item title="something">
    @item.css height: num
    return self

My proposal was to include namespaced attr syntax, where <div css:height=value> compiles to div.css('height',value). Then you could add your own as well, like <custom conf:name="Hey">. All you would need to do is define def conf key, value following the same pattern.

@judofyr suggested that we could instead stop discriminating between setters and regular calls in tags. That we could simply allow: <div.large css('height',value)> etc.

# special setter
def render
    <self> <div@item css:height=num title="something">

# allowing calls
def render
    <self> <div@item css('height',num) title="something">

The latter is certainly more flexible. This is also good if you sometimes want to call a method when tag is rendered (from the outer context). What do you think?

Parse error: Unexpected 'TERMINATOR'

stuff like this wont compile:

if var album = @albums.filter( do |a| a:id == parseInt(self:params:album) )[0]

Even this minimal case fails:

if filter(do yes)[0]
    yes

Export latest imba.js file

Is there a way to export the latest imba.js library file? I see that all your examples require imba.js

Imba events issues

Hello,

I've been playing with Imba for couple of days now and I am loving it so far.
Today I have been experimenting with events and it seems I'm stuck - I can't cancel the "tap" default event:

tag testing

    def taptest e
        e.cancel
        console.log e

    def render
        <self>
            <a href="#" :tap="taptest"> "Testing"

$$(body).prepend <testing>

I am also interested in using the Imba.Event.keycombo with the above code but the method spits out nothing. Am I missing something?

Any help is much appreciated.
Thanks!

body.onresize property seemingly can't be set

The following body.onresize property doesn't seem to be settable in Imba:

$$(body).dom:onresize = do
    #imgtag.render
    console.log "autoresizing"

Imba generates the correct code in app.js:

    q$$('body').dom().onresize = function() {
        id$('imgtag').render();
        return console.log("autoresizing");
    };

but it doesn't work in the browser - resizing doesn't cause any effect. Inspecting the body tag shows that .dom().onresize is undefined. Yet if I execute the above code directly in the console, the onresize function works. See http://udkk35438236.denyeo.koding.io/imba/

Any ideas? Could it because I need to register the 'resize' event in Imba?

Also, is there another way to detect and respond to window resizing?

Concerns separation

I do not know a lot about Imba internals, but... what do you think about separating DOM management from the language itself?
Like having an expressive language and a powerful framework based on it.

e.keychar is not working

For input with defined onkeypress e when I use e.keychar I get:

ReferenceError: TextEvent is not defined

Imba.Event.prototype.keychar = function (){
  if (this.event() instanceof TextEvent) {
 // ...

allow empty methods

this fails shortly:

def x

as well as this:

def x
  return

should be at least

def x
  'something'

bug or a feature?

browser/compiler.js is broken

browser/compiler.js is currently broken (it seems to miss the ./index-module).

Could I also suggest to name it imba.compiler.js? That means it would be possible to add the browser-directory directly to the load path for assets pipelines.

Ruby gem for imba?

Is there any way this can be ported to gem for ruby (since they are very alike) ? Thx.

Support for instantiating tags with dynamic name/type

@madmaniak proposed a syntax for creating tags by dynamic names. En example:

var items = [{type: 'post', title: "Hello"},{type: 'article', title: "World"}]

var tags = for item in items
    <{item:type} object=item> # etc

This should be rather trivial, and I think the syntax is pretty consistent with the dynamic things in tag like <div .{dynamic-class-name}> and <div@{custom-key}>. What do you guys think?

imba watch (versions 0.13.8 and 0.13.9) are not compiling .imba files to .js files

Figured out code causing this:

class Page
    prop name
    prop active

    def initialize name, active=false
        @name = name
        @active = active

    def get_current_user
        var url = "/current/user"
        var jqxhr = $.get(
            url,
            (do |data, status, xhr|
                console.log data
                console.log status
                @me.set_current_user data
            ),
         'json').fail(
                (do |xhr, status, error|
                    @me().show_failure(xhr, status, error)
                )
            ))

The extra ")" at the end caused the silent compiler error.

From output to console, it appears to work but no file is created and/or overwritten:

(compiling seems to be failing but without an error message -- I tried on a simple file and that compiled...)

imba watch ./src
dirname /home/mxvanzant/dev/tg/greenbook/code/gbwhat/public/app /home/mxvanzant/dev/tg/greenbook/code/gbwhat/public/app/src
--- watch dir: /home/mxvanzant/dev/tg/greenbook/code/gbwhat/public/app/src
--- write dir: /home/mxvanzant/dev/tg/greenbook/code/gbwhat/public/app/lib
17:29:37 compile src/app.imba to lib/app.js - 

Also install gave this warning:

npm update -g imba
npm WARN optional dep failed, continuing [email protected]
/home/mxvanzant/bin/node/bin/imba -> /home/mxvanzant/bin/node/lib/node_modules/imba/bin/imba
[email protected] /home/mxvanzant/bin/node/lib/node_modules/imba
โ”œโ”€โ”€ [email protected] ([email protected])
โ”œโ”€โ”€ [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected])
โ””โ”€โ”€ [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected])
mxvanzant@tg-mv-toshiba ~/dev/tg/greenbook/code/gbwhat/public/app $ imba -v
0.13.9

Directly running imba compile also does not work or give an error message...

Thanks!

Cannot get correct height and width of elements during initial render

I'm trying to resize (set the height and width of) an element based on the rendered height and width of another element. Specifically, I want to make a <div> (called markercontainer) the same size as a sibling <img> (called canvasimg).

After some experimentation, I attempted to read the size of canvasimg directly (using .dom()) in the render function:

    def render
        <self>
            (var canvasimg = <img.canvasimg src="img/interior-01.jpg">)
            (var markercontainer = <div.marker-container>
            ).css({height: canvasimg.dom():height, width: canvasimg.dom():width})

However, this didn't work - the returned height & width are both 0. The trouble may be that canvasimg hasn't yet been rendered (even after appending the entire app to body), so the height and width are 0.

I managed to get it working by re-rendering upon mousedown events. The full code:

var points = [ {top: '50%', left: '50%'}, {top: '25%', left: '75%'} ]
Imba.Events.register('mousedown')

tag #imgtag
    def onmousedown e
        @imgheight = $$(.canvasimg).dom():height
        @imgwidth = $$(.canvasimg).dom():width
        render

    def render
        <self>
            (var canvasimg = <img.canvasimg.size-to-window.max-height-70 src="img/interior-01.jpg">)
            (var markercontainer = <div.marker-container>
                for point in points
                    (var marker = <div.marker>
                        <img src="img/marker.png">
                    ).css(point)
            ).css({height: @imgheight, width: @imgwidth})

$$(body).append #imgtag

How would I use Imba to render this correctly from the start - page load - without any mousedown event? It doesn't work on Chrome though it worked on Firefox sometimes. Thanks for your advice.

More examples

I really love the syntax and apparent optimisations but I am struggling to find it useful when playing around.

Ideally what I need to see is some example of input creation, manipulation and binding. I'm not getting it with the examples and snippets currently available.

  • Data attributes.
  • Available events.

iScroll for scroller

Hi,

I'm trying to use iScroll for the infinite scroll example. I have the following code, but it's not working.

tag sample

    def build
        @offset = 0
        @rows = 10
        # render the whole app every other frame or so
        # since imba is so efficient in rendering, this
        # is actually much faster than tracking changes
        # and only rendering views that have changed etc
        setInterval(&,1000 / 60) do render
        self


    def count
        Tasks:length


    def render
        var from = @offset
        var to = from + @rows

        <self>
            <div .topcoat-list>
                <h3 .hw .topcoat-list__header> "{count} tasks - (showing {from + 1} to {to})"
                <ul#scrollable.topcoat-list__container>
                    for i in [from ... to]
                        var item = Tasks[i]
                        continue unless item
                        # this is where the whole magic happens
                        # we only loop through the rows that should be visible
                        # and we use a special cachekey for the nodes
                        # modding the current index to reuse rows for nodes
                        <li@{i % (@rows * 2)}.hw .completed=(item.completed) :tap=['complete',item] .topcoat-list__item>
                            <div.checkbox>
                            <div.title> "{item.desc}"


    def complete task
        task.complete


    def scroll e
        e.cancel
        var w = e.event:deltaY
        var d = Math.round( (Math.abs(w) + 500) / 500) * (w > 0 ? 1 : -1)
        @offset = Math.max(0, Math.min(@offset + d,count - @rows))

# add an instance of sample the body
$$(body).append <sample>
extern IScroll;
new IScroll('#scrollable')

I'm not sure how I can reference the UL tag to make it scrollable by touch. I imagine I would have to create a new Tag and nest it in the Sample tag? Any guidance you can provide would be amazing.

Great work on the project so far! This has great potential.

Setters without explicit return should automatically return self

If you do not return explicitly from a setter method (def something=) it should default to returning self. Imba relies on this for tags (every tag is compiled to a chain of method calls, all of which should return the tag itself). It does not affect code like var val = item.something = 10 since Imba takes care to use assign the actual value to both val and item.something.

Please contact me

This is Paul Krill of InfoWorld.com. I would like to ask you some questions about your Imba project. Sorry to have to use this issues forum as a way to contact you.

Sprockets error with 0.14.3

After updating imba-source to 0.14.3 I get a Sprockets error when using Imba with Rails.

Sprockets::FileNotFound - couldn't find file 'imba' with type 'application/javascript':
  sprockets (3.4.0) lib/sprockets/directive_processor.rb:182:in `rescue in block in process_directives'
  sprockets (3.4.0) lib/sprockets/directive_processor.rb:179:in `block in process_directives'
  sprockets (3.4.0) lib/sprockets/directive_processor.rb:178:in `process_directives'
  sprockets (3.4.0) lib/sprockets/directive_processor.rb:83:in `_call'
  sprockets (3.4.0) lib/sprockets/directive_processor.rb:68:in `call'

redundant coma between last argument and `do`

Imho, save data do looks much more natural than save data, do

i understand it's just a caprice but permanently switching between Ruby and Imba makes me forget about that coma.

and when adding it my eyes ache :)

Support for generators?

Supporting generators enables support for coroutines, which makes asynchronous code a lot easier to reason about.

If-expression inside tags gets wrong cache key

tag foo
    def render
        <self>
            if true
                <h3> "hello"
                <h3> "world"

Compiles to:

return this.setChildren((true) && (
    [(this[-1] = this[-1] || t$('h3')).setContent("hello").end(),
    (this[-1] = this[-1] || t$('h3')).setContent("world").end()
    ]
)).synced();

The error seems to be caused by the key being chosen by var key = parent.tree.indexOf(self), and self isn't a children of the foo-tree.

installation warnings: optional dependencies

i know these are just warnings, and the npm packages are very fast moving targets[1], but maybe it'd be cool if we could catch them earlier, rather than later:)

igalic@levix ~/s/m/hello-world-imba (master=) [34]> sudo -H npm install -g imba
[sudo] password for igalic: 
npm WARN optional dep failed, continuing [email protected]
/usr/bin/imba -> /usr/lib/node_modules/imba/bin/imba
npm WARN unmet dependency /usr/lib/node_modules/keybase/node_modules/gpg-wrapper requires iced-coffee-script@'~1.7.1' but will load
npm WARN unmet dependency /usr/lib/node_modules/keybase/node_modules/iced-coffee-script,                                                                                  
npm WARN unmet dependency which is version 1.7.1-b
npm WARN unmet dependency /usr/lib/node_modules/keybase/node_modules/triplesec requires iced-coffee-script@'~1.7.1' but will load
npm WARN unmet dependency /usr/lib/node_modules/keybase/node_modules/iced-coffee-script,
npm WARN unmet dependency which is version 1.7.1-b
npm WARN unmet dependency /usr/lib/node_modules/keybase/node_modules/triplesec/node_modules/more-entropy requires iced-coffee-script@'*' but will load
npm WARN unmet dependency /usr/lib/node_modules/keybase/node_modules/iced-coffee-script,
npm WARN unmet dependency which is version 1.7.1-b
npm WARN unmet dependency /usr/lib/node_modules/keybase-installer/node_modules/gpg-wrapper requires iced-coffee-script@'~1.7.1' but will load
npm WARN unmet dependency /usr/lib/node_modules/keybase-installer/node_modules/iced-coffee-script,
npm WARN unmet dependency which is version 1.7.1-a
[email protected] /usr/lib/node_modules/imba
โ”œโ”€โ”€ [email protected] ([email protected])
โ”œโ”€โ”€ [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected])
โ””โ”€โ”€ [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected])
igalic@levix ~/s/m/hello-world-imba (master=)> npm --version
2.13.5
igalic@levix ~/s/m/hello-world-imba (master=)> node --version
v0.10.40
igalic@levix ~/s/m/hello-world-imba (master=)> 

[1]: some people have automated the fastmovingness away, and have their ci deal with versioning: semantic-release (a.k.a.: http://hauptversionsnummernerhoehungs.angst.software/ )

Doesn't Compile on Windows

I'm using win-7 64-bit. I installing imba with npm gave the follwing output:

E:\workspace\npm>npm install -g imba
npm WARN optional dep failed, continuing [email protected]
C:\Users\hrzafer\AppData\Roaming\npm\imba -> C:\Users\hrzafer\AppData\Roaming\np
m\node_modules\imba\bin\imba
[email protected] C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba
โ”œโ”€โ”€ [email protected] ([email protected])
โ”œโ”€โ”€ [email protected] ([email protected], [email protected], escape-string-regexp@1
.0.3, [email protected], [email protected])
โ””โ”€โ”€ [email protected] ([email protected], [email protected], [email protected], glob-pa
[email protected], [email protected], [email protected], [email protected], [email protected]
.0)

I think it is installed properly anyway

E:\workspace\npm>imba

  Usage: undefined [options] [command]
[...]

Then I created a directory, created another called src, copied hello.imba and tried to compile:

E:\workspace\npm>imba watch ./src
dirname E:\workspace\npm E:\workspace\npm\src
--- watch dir: E:\workspace\npm\src
--- write dir: \E:\workspace\npm\lib
fs.js:747
  return binding.mkdir(pathModule._makeLong(path),
                 ^
Error: ENOENT, no such file or directory 'E:\E:.'
    at Error (native)
    at Object.fs.mkdirSync (fs.js:747:18)
    at ensureDir (C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba\lib\compiler\cli.js:202:8)
    at writeFile (C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba\lib\compiler\cli.js:333:3)
    at EventEmitter.<anonymous> (C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba\lib\compiler\cli.js:447:12)
    at EventEmitter.emit (events.js:118:17)
    at EventEmitter.<anonymous> (C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba\node_modules\chokidar\index.js:137:38)
    at EventEmitter.FSWatcher._emit (C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba\node_modules\chokidar\index.js:152:5)
    at EventEmitter.NodeFsHandler._handleFile (C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba\node_modules\chokidar\lib\nodefs-handler.js:275:10)
    at EventEmitter.<anonymous> (C:\Users\hrzafer\AppData\Roaming\npm\node_modules\imba\node_modules\chokidar\lib\nodefs-handler.js:468:21)

I also tried to copying imba.js to the same place with src, tried again and got this error message window:

capture

tag$.$textarea().setStyle is not a function

I tried this imba code:

<textarea style="font-size: 12px"> "This text is inside the textarea."

I got this error:

[Error] TypeError: tag$.$textarea().setStyle is not a function. (In 'tag$.$textarea().setStyle("font-size: 12px")', 'tag$.$textarea().setStyle' is undefined)
    render
    build
    end
    (anonymous function)
    (anonymous function)

Module support?

I found some files in the repo that seem to indicate Imba having support for modules.

Is this already working and how it can be used? Or if not, is there any plans to support this?

And what about importing and using JS modules?

This is, IMHO, the best missing feature in coffeescript, and something I've come to rely on with ES6.

Other than that, Imba language looks very promising. I have to take it for a spin next time I have a short task to do.

Indicate and implement that Indentation is canonically tabs-only

The imba documentation does not indicate what constitutes valid indentation.

In discussion with @somebee there was agreement that it is tabs only.

Please document & adjust the lexer to only use tabs as indentation.

I'm looking through the lexer now to see if I can find where the lexer makes that decision.

Imba todomvc benchmark is cheating :(

(Posted this comment on HN, but figured I'd copy it here for discussion.)

I just spent an hour looking at the Imba benchmark. Yep, it's cheating. Which is a shame, because I really like the framework as a whole.

The vast majority of the speedup comes from a single sneaky line of code. The majority of their "Everything" benchmark's time is spent in the reorder step. They've implemented this as "remove a random todo, render, push the removed todo back onto the end, render." The Imba implementation, and it alone, caches the rendered todo view, so that they can re-use it once the todo is reinserted.
This single optimization is responsible for the vast bulk of their claimed speed. Removing it puts Imba only 2x faster than React, not 60x.

If you want to try it yourself, look at line 55 of app.js. Change:

    res.push((this['_' + todo.id] = this['_' + todo.id] || t$('todo')).setObject(todo).end());

... to:

    res.push(t$('todo').setObject(todo).end());

Furthermore, this isn't a caching strategy you'd want to use in a real app. It holds onto all DOM nodes ever created, thereby leaking quite a lot of memory.

Again, I think Imba is cool, and fast, just not otherworldly fast. I hope this was just an "oops!" and not an intentional misrepresentation.

Remove is not working

I am working from the master branch.

<div.btn.btn-danger.input-group-addon :tap='remove_input'> "X"

def remove_input e
    console.log e.target.parent.parent.remove

Doesn't work but...

def remove_input e
    console.log e.target.parent.parent.empty

does work. Of course it only removes children and not the parent element as well.

Using imba with Foundation 5 css framework custom attribute containing dash "-" doesn't compile.

Hi. I'm attempting to use imba with Foundation 5 CSS framework. For example, when creating a top menu bar (nav bar), imba compiler gives error on the data-topbar custom attribute:

def top_bar name
  <div.fixed>
    <nav.top-bar data-topbar role='navigation'>
      <ul.title-area>
        <li.name>
          <h1>
            <a href='#'> name

I get:

[0:1] Parse error on line 3: Unexpected 'CALL_START'

Any ideas? Thanks! BTW, really liking imba!!!

Problem with preventing click event

I have such definition in layout:

        def ontap
                Dispatcher.trigger "cancel"

And it prevents me from using native <a> tag. Browser is not reacting after click.
I'm not calling e.halt or e.cancel so I expect none event will be blocked by above definition.

I think it happens here:

        Imba.Events.register('click',function(e) {
            // Only for main mousebutton, no?
            if ((e.timeStamp - lastNativeTouchTimeStamp) > lastNativeTouchTimeout) {
                var tap = new Imba.Event(e);
                tap.setType('tap');
                tap.process();
                if (tap._responder) {
                    return e.preventDefault(); // <---- HERE!
                };
            };
            // delegate the real click event
            return Imba.Events.delegate(e);
        });

Caching static attributes

I have recently implemented caching of static attributes in tag trees. Opening this issue for further discussion, as i'd like to know whether you guys think it is a good idea or not.

In most apps and websites, most dom-classes, attributes and textContent will be static. When calling render in Imba (with cached nodes) there should not be any reason to call setType('text') on every input every time etc. In Imba it is possible to change these attributes from outside the render function though, and usually you would expect a render to reset / update everything.

My proposed (and shipped) solution is to cache everything that is known to be static, with one exception.

tag post
    def render
        <self>
            <h1> "Cached title"
            <input.cache type='text' tabindex=3 >
            <input.cache .nocache=yes type=('text') tabindex=(2) >

if you don't want to cache a certain static attribute the first time (rather make it set every time you call render), you can wrap the value in parenthesis: <input type=('text') tabindex=(2) >. If you want a class to be reapplied on every render you simply use the toggle syntax with <post .myflag=yes >

Sure, the compiler still knows that (2) is static, but I'm thinking that wrapping in parenthesis could be a decent syntax to signal that it is a 'dynamic' value. But I'm obviously posting it here since I expect there could be more elegant solutions.

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.