Next-generation DOM manipulation

Related tags

Frameworks ractive
Overview

Ractive.js - Next-generation DOM manipulation

npm version Build Status Coverage Status jsDelivr downloads npm downloads Twitter Follow

Have any questions or just want to chat? Join us on GitHub Discussions!

What is Ractive.js?

It's a JavaScript library for building reactive user interfaces in a way that doesn't force you into a particular framework's way of thinking. It takes a radically different approach to DOM manipulation - one that saves both you and the browser unnecessary work.

Features include...

  • Data-binding, with a beautiful declarative syntax.
  • Event handling that doesn't make you tear your hair out.
  • Flexible and performant animations and transitions.
  • And much more!

Getting started

To get a feel for how it will make your life as a web developer easier, head over to the documentation at ractive.js.org or get a quick hands-on with interactive tutorials.

Contributing

All forms of help are welcome! Please read CONTRIBUTING.md to learn how to contribute.

License

Copyright (c) 2012-21 Rich Harris and contributors. Released under an MIT license.

Comments
  • Re-branding's proposal

    Re-branding's proposal

    Warning, almost manifesto. Reading carefully! ))))))

    Hi everyone - maintainers and developers!

    I believe that Ractive is the most simple, but the most powerful front-end framework I ever used. In past, I'd used Backbone and Angular. Quite recently, I'd tried React and Vue. But no one of them could give me the same simplicity, convenience, and functionality that Ractive gives.

    In spite of the fact that Ractive is an excellent tool for building web apps, he isn't so popular, even in comparison with younger colleagues (hi Vue). And our community isn't very numerous. 5К+ stars on GitHub are not the most outstanding result.

    However, Ractive is still alive and develops. Thank you very much @evs-chris, @fskreuz, @martypdx and other guys who maintain it. And of course to you @Rich-Harris, founder of Ractive.

    I use Ractive in my work since 2013. Now in the end of 2017, we are very close to version 1.0. I believe it could be a turning point in the history of Ractive. I believe we could make Ractive more widespread and popular to involve new developers and maintainers.

    To do that, we need to not only develop Ractive itself but also to form an ecosystem around him. We need to have awesome docs, awesome plugins and libs, awesome learning materials and other resources. And also we need to make little bit more marketing activities.

    My version of the new logo you can find here. As you can see, the main concept is as though the logo is an element of a Periodic Table. I think it's quite cool. Also, I offer to change Ractive's slogan to something short and simple to read. I found this article by Eugene Mirotin from TopTal and I think what its title is what we look for - "Ractive.js - Web Apps Made Easy".

    Thanks that you have read it. Please, leave your comments and put a thumb up if you agree with my proposals. Thus I will be able to estimate a need for this work. Also, I hope that my logo and slogan become a part of new Ractive's brand.

    Good luck!

    UPDATE:

    Ractive's new logo I offer:

    ractive-logo-small

    meta/general 
    opened by PaulMaly 88
  • Discussion: should we deprecate the old proxy event syntax?

    Discussion: should we deprecate the old proxy event syntax?

    This follows on from the discussion on #1146 - see in particular feedback from @thomsbg (https://github.com/ractivejs/ractive/pull/1146#issuecomment-53526330) and @unity (https://github.com/ractivejs/ractive/pull/1146#issuecomment-54030188).

    As of 0.5.6, we have two ways of dealing with events:

    Direct method call (new style)

    <button on-click='set("selected",foo)'>select foo</button>
    

    Triggering a proxy event, and handling it separately (old style)

    <button on-click='select:{{foo}}'>select foo</button>
    
    ractive.on( 'select', function ( event, selected ) {
      this.set( 'selected', selected );
    });
    

    These two are functionally identical, but semantically very different - the new syntax is far more concise and convenient, but introduces a coupling (between the event and the action) that wasn't there previously. For example, if you were using a Flux-style architecture, you wouldn't want to set() data directly.

    Option 1: deprecate

    If we did deprecate the old syntax entirely, you can still maintain that decoupling:

    <!-- this... -->
    <button on-click='fire("select",event,foo)'>select foo</button>
    
    <!-- is identical to this: -->
    <button on-click='select:{{foo}}'>select foo</button>
    

    You can also call custom methods so that you're not blindly setting data, but calling the same API that you'd call programmatically:

    var TodoList = Ractive.extend({
      add: function ( description ) {
        // any validation etc goes here...
        this.push( 'todos', { done: false, description: description });
      }
    });
    

    Pros:

    • eliminates code from the codebase - makes it slimmer, more maintainable
    • reduces the amount of stuff newcomers have to learn
    • removes potential confusion
    • we don't lose any expressive power

    Cons:

    • on-click='fire("select",event,foo)' is more verbose than on-click='select:{{foo}}'
    • 'Proxy events' (i.e. 'click means select') are second-class citizens - some people prefer the proxy event style

    Option 2: Keep both syntaxes

    Pros:

    • Keeps existing users happy, means no breaking changes down the line
    • Keeps proxy events as first-class citizens

    Cons:

    • Codebase size and maintainability
    • Potentially confusing for newcomers

    Option 3: Keep old syntax, but disallow arguments

    One idea we briefly tossed around was keeping on-click='foo' as a short version of on-click='fire("foo",event)', but disallowing additional arguments. This alleviates the problem of situations like

    <widget on-foo='bar:{{these}},{{are}},{{ignored}}'>...</widget>
    

    In that example, the bar handler receives the original foo event's arguments - the additional arguments are ignored. We don't have a particularly good way around this. Disallowing arguments masks this problem rather than solving it, but maybe there's some value in it.

    Pros/Cons:

    • Erm... not quite sure

    Option 4: Modify old syntax

    If you think about it, the curly braces are fairly redundant. For data-binding, they serve as delimiters - it says...

    {{ <!-- references to the viewmodel are allowed in here --> }}
    

    ...but with method calls, the directive itself serves that purpose:

    <button on-click='doSomething( /* references are allowed in here */ )'>click me</button>
    

    We could apply the same logic universally and just do away with the curlies...

    <button on-click='select:foo'>select foo</button>
    

    ...though for the sake of avoiding total confusion, it'd probably be better to go with something different, such as...

    <button on-click='select[foo]'>select foo</button>
    
    <!-- If there we no arguments, syntax would be as currently is: -->
    <button on-click='select'>select</button>
    

    ...which I personally find rather appealing. It gives us the opportunity to reverse an earlier mistake (whereby anything that couldn't be parsed was simply treated as a string - so select:xyz meant the same as select:"xyz" - bad API decisions are often made in the name of being 'forgiving' and 'flexible'. Mea culpa), and works equally well for decorators and transitions.

    Pros:

    • The 'array syntax' (let's call it that) is more compact than existing syntax
    • Easy to parse using same mechanisms as method calls, so still gives us opportunities for code removal
    • The arguments look like valid JavaScript! (Because they are)
    • We don't need to do any data-binding - there's actually a small performance win with this approach (values only need to be got when the event actually happens), less state to manage and observe
    • Proxy events are still first-class
    • Adapts to decorators and transitions

    Cons:

    • Still involves two separate concepts for newcomers to learn
    • Will be a breaking change when support for existing syntax is finally turned off

    So: would love to know what everyone thinks. Options 1 and 4 are my personal favourites, but your needs may well differ from mine. One thing I will say - I don't think we should worry about deprecating things. Ractive is still relatively young, and it's better that we take opportunities to get things right rather than trying to prevent the pain of updating existing templates. Deprecations can be well signposted with appropriate console warnings etc.

    Thanks everyone.

    meta/general 
    opened by Rich-Harris 83
  • Ractive js not working on iOS 9 Safari - iPad & iPhone

    Ractive js not working on iOS 9 Safari - iPad & iPhone

    Hello,

    I found a critical bug with ractive js on iOS 9 Safari. The problem is that the page can't be loaded and keeps refreshing until Safari get message "A problem repeatedly occurred on page"

    Try some of the examples on http://examples.ractivejs.org/, some of them have problems with loading, eg.: http://examples.ractivejs.org/illustration

    This problem occurs on heavy load applications with lot of code in template. Our application has 1110 rows in template and it fails to load it. But if we limit it on 300 it works.

    Any help is appreciated, I spent some time on debuging this and it's only happening on iOS 9 devices. On iOS 8 devices it's working, but the loading is extremely long.

    bug/major enhancement/performance 
    opened by lubomirblazekcz 63
  • Event expressions - RFC

    Event expressions - RFC

    This is my attempt to resolve #1172, #1396, #2311, and partially #2176. It is also somewhat tied to #2369.

    What this does

    This takes event handling and unifies it as an expression instead of having special parsing for handling method events. This opens event handling up to everything possible with an expression in Ractive. Here're a few examples:

    • call data methods e.g. on-click=".loadStuff()"
    • call more complex structures e.g. on-click="@this.reset.partial('foo')" or on-click=".foo().and.bar(., 'yep')"
    • call parent methods for tightly integrated (container) components e.g. on-click="@this.parent.doAThing(.)"
    • chain multiple actions in an event handler e.g. on-click="@this.toggle('foo') && @this.fire('fooed')" or since these are parsed as a list on-click="@this.toggle('foo'), @this.fire('fooed')"
    • the code is a lot smaller and generally easier to follow as a result

    I have also taken the spread args and made it available anywhere, which is what ES2015 allows e.g. on-foo="fn('hi', ...arguments, 42)" is perfectly legal. It is also extended to any other call expression with any reference e.g. {{ doThing(foo, ...bars, baz, ...bats) }}. I implemented this by half-shimming with an IIFE based on Babel's output. There may be a better way, but this didn't require an extensive refactor.

    Additionally, dollar args ($1) and arguments refs are now allowed to have children as per #2311. These are handled in the same way as event refs with children.

    Comments specifically requested

    Updated

    1. ~~Method events are handled in their current state my detecting basically ^someName(.*)\s*$, prepending @this., and handling as an expression. This seems to work pretty well in practice, but is it confusing that toggle('foo'), .toggle('foo'), and ~/toggle('foo') mean potentially very different things? With the confusion surrounding where method events actually call, should they just be deprecated and eventually removed in favor of @this.method(args)? Deprecating and removing plain method call events would eliminate the remaining inconsistency in template reference resolution.~~ Consensus is that non-specific calls should be removed, so they are deprecated here and would be removed later.
    2. ~~I haven't addressed proxy events in this PR yet, because I'd like some feedback first. I would prefer to support only no-args events (option 3) for auto-proxying, which would be super simple to support here. Is that what most people would like to do? The only other thing I consider tenable from a parsing (code and mental) viewpoint is to support on-click="nameExpression:argsList". That would make on-click="{{ foo ? 'bar' : 'baz'}}: {{bop}},bip,{{ { oh: 'my' } }}" become on-click="( foo ? 'bar' : 'baz' ): bop, 'bip', { oh: 'my' }".~~ Argumented proxy events are deprecated here and would be removed later.
    3. ~~I also haven't addressed decorator and transition args yet, because I'd like some feedback first. I would prefer to drop mustaches in the directives entirely and just move to comma separated expression lists for decorators and transitions. That combined with as-decoratorName and transitionName-in/transitionName-out/transitionName-in-out (or something similar) and the changes in #2369 would allow that. This would be more consistent with event directives. Another proposal has been to treat them as method calls instead e.g. decorator="decoratorName(arg1, arg2)" which seems reasonable, but I think it's less consistent and could get weird with transitions with their in/out/in-out facets.~~ This is addressed in #2369.
    4. ~~How should deprecation be handled?~~ I'd kinda like for this to land for 0.8 now, since it's still compatible with 0.7 and would let the big cleanup start immediately after 0.8.

    Status

    • [x] Handle method events as expressions
    • [x] Account for spread, arguments, and dollar args in expressions
    • [x] Allow children of dollar args and arguments
    • [x] Allow spread args in any invocation (it's there, so may as well use it, no?)
    • [x] Tests ~~, tests, and more tests~~ - the deprecation path leaves the old proxy handling code in place, so only expression-related stuff is tested beyond the existing event tests
    • [x] Finalize deprecation path
    • [x] ~~Clean up code~~ mostly deferred until after deprecation cycle - there's lots of code that can go away and/or be nicely refactored
    opened by evs-chris 62
  • WIP: Keypaths FTW

    WIP: Keypaths FTW

    This is the start of moving viewmodel functionality into Keypath objects. At this point, viewmodel doesn't have caches anymore for values, computations, and wrappers - and the get and clearCache functionality have also been moved into the Keypath objects.

    This means not having to do multiple hash lookups on each get. And it also begins to consolidate the logic around managing a particular keypath value.

    Just the start of the process, remaining would be

    • move other viewmodel methods
    • optimize mappings by reusing Keypath object when keypath is the same or aliasing
    • move dependency tracking
    • I think reference resolving can be improved as well
    opened by martypdx 48
  • Attach multiple decorators

    Attach multiple decorators

    I was under the assumption that you could attach more than one decorator. We are attempting to have 2 decorators. One for editing, and one for validating.

    Although it appears that you can only have one decorator per element. So I guess this is a feature request to have more than one decorator per element.

    http://jsfiddle.net/M3MkH/

    enhancement/general 
    opened by browniefed 48
  • Progressive enhancement

    Progressive enhancement

    Actually when we prerender Ractive template on server, then try to rerender them on client the dom is replaced. Do you think it would be possible to have an options that would allow Ractive to not replace the dom but use the already built in one ? To ensuring that the dom already present would be the same that the dom produced prehaps you could use some kind of checksum (a little alike what React guys do)

    Thanks for your work anyway

    enhancement/general 
    opened by fdecampredon 45
  • New feature: import components from HTML file

    New feature: import components from HTML file

    This probably isn't fully baked yet, but it's a really neat idea (suggested by @davidmoshal in #299), and I'd be interested in feedback.

    The idea is to be able to fully define components in a single file that contains the template, any CSS, and custom methods/init logic. It draws inspiration from Web Components and HTML Imports. If we get it right, it will make it really easy to create reusable components that can be shared widely (think Ractive UI, like jQuery UI or Angular UI, except not an unloved cousin to the main project :)

    Making a component

    You define a component in an HTML file (because HTML can contain <style> and <script> tags, and text editors are happy to chop and change syntax in that situation - much better than the nightmare that is multiline string templates in a .js file).

    <div class='box' style='width: {{size}}px; height: {{size}}px'>
      <p>This box has a total area of {{ format(size*size) }}px.</p>
    </div>
    
    <!-- This CSS will be appended to the page when the first instance
         of this component is created, and removed when the last instance
         is torn down. It is optional. There's no scoping magic, we have to
         just be careful with class names -->
    <style>
      .box {
        background-color: black;
        color: white;
      }
    </style>
    
    <!-- The script block is optional (as is the style block) -->
    <script>
      module.exports = function ( Ractive ) {
        return Ractive.extend({
          init: function () {
            console.log( 'initialising box!' );
          },
          data: {
            size: 200,
    
            // add comma separators
            format: function ( num ) {
              var remaining = '' + num, result = '', lastThree;
    
              while ( remaining.length > 3 ) {
                lastThree = remaining.substr( -3 );
                result = ( ',' + lastThree + result );
    
                remaining = remaining.substr( 0, remaining.length - 3 );
              }
    
              return remaining + result;
            }
          }
        });
      };
    </script>
    

    Loading the component

    Then you load the external file in one of two ways:

    1. As a globally available component

    <!doctype html>
    <html>
      <head>
        <title>Component imports test page</title>
    
        <!-- here is where we import the component. We could add a 'name'
             attribute, otherwise it will default to Ractive.components.box -->
        <link rel='ractive' href='box.html'>
      </head>
    
      <body>
        <div id='container'></div>
    
        <script src='Ractive.js'></script>
        <script>
          var box;
    
          Ractive.load().then( function () {
            box = new Ractive.components.box({ el: 'container' });
          });
        </script>
      </body>
    </html>
    

    2. Loading a specific component

    <!doctype html>
    <html>
      <head>
        <title>Component imports test page</title>
      </head>
    
      <body>
        <div id='container'></div>
    
        <script src='Ractive.js'></script>
        <script>
          var box;
    
          Ractive.load( 'box.html' ).then( function ( Box ) {
            box = new Box({ el: 'container' });
          });
        </script>
      </body>
    </html>
    

    The 'box.html' path will be resolved relative to Ractive.baseUrl, if it exists (so you could put all your components in a components or imports folder without having to explicitly refer to that folder each time).

    Dependencies

    Some components might have dependencies on other components. One way to handle that is to have separate <link> tags for them all, so that all components are globally available. Another is to use the @import directive:

    @import foo.html
    @import ../bar.html
    @import somethingElse.html as baz
    
    <div class='component-zoo'>
      <h2>This is a foo</h2>
      <foo/>
    
      <h2>This is a bar</h2>
      <bar/>
    
      <h2>This is a baz</h2>
      <baz/>
    </div>
    

    Cross-origin stuff

    The html files have to be hosted on the same origin, or served with appropriate CORS headers.

    Optimisation

    Clearly this is isn't a great way to build large apps, because you don't want to have to make a ton of requests. At some point in the future there'll be a build tool that will compile components (and their dependencies) into a JavaScript bundle, that would work with grunt et al - the Ractive AMD loader plugin will also serve this purpose (when used with the RequireJS optimiser). Uncompiled component imports won't work with the runtime builds, as they need to be parsed.

    Promises (an aside)

    Under the hood, this is using promises. (If any promises experts out there can see any ways in which this implementation deviates from the spec, let me know!) I'm tempted, now that they're in the library, to start using them in other places (e.g. returning a promise from ractive.set() and ractive.animate() etc, rather than using callbacks and making them chainable)... any thoughts?

    How to start testing them

    Grab the latest dev build from https://github.com/RactiveJS/Ractive/tree/0.4.0/build.

    Just to clarify - nothing is set in stone here - the Ractive.load() method name, the <link> approach, the component format, the @import directive - it's all just fodder for discussion at this point. If you have better ideas please share them!

    enhancement/general 
    opened by Rich-Harris 44
  • Memory leak when using components

    Memory leak when using components

    Description:

    Took me hours to pin this issue down in my SPA, but finally managed to reproduce it in a few lines of code πŸ˜ͺ Looks like Ractive 0.8 keeps pointing to unused DOM elements (and possibly something else? whole components?) after their component is teardown.

    This may result in big memory leaks, depending on the size of your components. The more the elements, the bigger the memory being leaked.

    I started noticing it on components where 4k-20k elements were being removed. Narrowed it down to a minimal example.

    Let me know if I can be of any help.

    Versions affected:

    0.8.11 notably, 0.7.3 is NOT affected

    Platforms affected:

    Any browser

    Reproduction:

    http://jsfiddle.net/trc4m077/4/

    1. fire up the inspector (ex. Chrome)
    2. activate inspector's Memory tab
    3. click the button "TOGGLE ME", from my fiddle
    4. use the Inspector to take a Heap Snapshot
    5. filter objects by using the Class filter: "detached DOM Tree"

    you should see 3 groups of Detached DOM Tree:

    • ignore the first two, which are related to jsFiddle
    • the third one should include 4 entries, all of which appear to be linked to Ractive

    Those 4 entries will be a lot more, if you're building anything more complex than my example.


    See also the attached screenshots from my inspector. All screenshots have been taken after ApplicationHeader had been toggled off.

    memory leak

    component is still kinda alive

    node is detached

    Code:

    Interestingly, if you remove the {{name}}, no memory will be leaked.

    From my tests, memory leaks even if ApplicationHeader is marked as isolated: true, and name gets passed via attribute.

    const ApplicationHeader =  Ractive.extend({
      template: `
        <nav class="header">
          <section>
            My name is {{name}}
          </section>
        </nav>
      `,
    });
    
    const Application = Ractive.extend({
      template: `
      <button on-click="toggle('hideComponent')">TOGGLE ME</button>
      {{#if !hideComponent}}
        <ApplicationHeader/>
      {{/if}}
      `,
    
      components: {
        ApplicationHeader,
      },
    
      data: () => ({
        name: 'Laser',
      }),
    
    });
    
    
    window.r = new Application({ el: '#application' });
    
    bug/major enhancement/performance 
    opened by giovannipiller 39
  • Dynamic Partials switcher

    Dynamic Partials switcher

    I am trying to get started with Ractive but could not make simple partials template switcher to work. I know, this has been discussed before but still, could not understand when setTemplate called inside Ractive Component and how to use it to switch component's template.

    var dynamicPartial = Ractive.extend({ 
        beforeInit: function(o){
            o.template = '{{>' + o.data.partial + '}}'
        },
        setTemplate: function(o) {
         o.partials.dynamicPartial = o.data.partial;
       }
    })
    var r = new Ractive({
        el: document.body,
        template: '#template',
        components: {
           dynamicPartial: dynamicPartial
        },
        data: {
            showJSON: function (json) {
                return JSON.stringify(json);
            },
            partials: ['p1', 'p2', 'p3'],
            partial: 'p2',
            user: {
                name: 'Sergey', id: 234, email: '[email protected]'
            }
        }
    })
    
    r.on('changeView', function(event) {
        event.original.preventDefault();
        r.set('partial', event.node.attributes.viewname.value);
    });
    

    So, what is setTemplate when it is called and how to use it ? Full, not working example is here: http://jsfiddle.net/9Vja5/27/

    Thanks for help!

    opened by kurdin 38
  • The road to Ractive 0.8 is tree-lined

    The road to Ractive 0.8 is tree-lined

    Brace yourselves: a tsunami of text approaches. I've been squirreling away on this branch for a while now without sharing the progress, which, although necessary – due to a) the magnitude of the changes and b) uncertainty over whether they'd pan out – isn't how I like to work. This PR (which isn't ready for merge) is intended to bring the changes into the open and explain how 0.8 will most likely differ from 0.7.

    Those of you who follow Ractive's development will be aware of #1740, an epic pull request by @martypdx. Marty had a Eureka moment a while back relating to how data changes propagate through Ractive instances, and #1740 applied that insight to the existing codebase. Unfortunately, as I contributed to #1740, I came to realise that the technical debt in the codebase (incurred when Ractive was my solo project, I hasten to add) made such large-scale changes extremely difficult, and I began to wish we could rewrite it as though Marty had designed it in the first place.

    This is that rewrite. It's based on #1740, and aims to achieve the following:

    • Replace the 0.7 (and earlier) viewmodel concept with a lighter tree-like structure (as per #1740)
    • Apply the same thinking to the way DOM updates are applied. More on this below
    • Make the codebase lighter and more readable

    The first of these is all about performance. While Ractive comfortably bests most of its competitors in typical scenarios when it comes to DOM update performance, templates with hundreds of components are sluggish on initial render, which is often when performance is most critical. This is largely due to some convoluted caching logic that becomes unnecessary when you model things the right way.

    The second is also performance related, but is also a big win for simplicity. As with the data side of things, thinking about DOM updates in terms of trees makes a lot of the indirection in the current codebase unnecessary. Tricky issues like #1986 should be much easier to resolve.

    The third bullet point is perhaps the most important. Time and again, people tell us that they'd love to contribute, but that the codebase is too overwhelming to get a handle on. That's a great shame, and left unchecked will slow Ractive's development down. This PR won't fix that in one go, but I'm confident that it's a major step in the right direction.

    Executive summary of the changes

    Fewer modules

    The current codebase is characterised by lots of tiny modules. In many cases that's unnecessary, because those modules are only used in one place (e.g. they define a method on an internal class). In this PR, you're more likely to see one file per class than one file per method. This is partly an aesthetic choice (I think it's easier to read), but largely motivated by the use of ES6 classes, which have a more streamlined syntax that encourages this form. (The class keyword is much maligned, but is actually very well suited to Ractive's ontology, at least internally.)

    Note: our build process will need to be updated to accommodate classes – at present, Babel's classCallCheck helper is included many times when it only needs to be there once.

    viewmodel -> model, virtualdom -> view

    Strictly speaking it doesn't make sense to say that these folders have been renamed, since their contents are all new. But the responsibilities of the things formerly found in src/viewmodel now reside in src/model, and likewise with src/virtualdom and src/view.

    Partly this is because even though Ractive isn't an MVC library in the traditional sense, those terms are well-understood and the division of responsibilities is easy to grok. But mostly it's because I like to be able to use bash autocomplete after typing the first couple of letters of a directory name, and 'v, i, TAB, nope, e, whoops, BACKSPACE, r, TAB' was driving me mad.

    Trees

    As alluded to, 0.8 is all about trees. Each value in your data object is represented by a Model. If you have this...

    var ractive = new Ractive({
      data: {
        foo: {
          bar: 42
        },
        baz: 'childless'
      }
    });
    

    ...then the root node has two children with the keys foo and baz. foo is a branch (with a child, bar), baz is a leaf. Each node is aware of its immediate parent-child relationships, and of things that depend on its value. Models are created 'lazily' (i.e. as and when they become necessary for Ractive to track).

    An instance's 'root model' (the equivalent of ractive.viewmodel in 0.7 – will most like become ractive.model, I suppose) is just another node, with a few minor differences; ditto computed values.

    As soon as a model changes value (internally, model.set(newValue)), each of its dependencies are notified of the change (via their handleChange methods). There's no longer any need to distinguish between different types of dependant (e.g. computation, observer, virtual DOM node). When a virtual DOM node (hereafter, 'view') is notified in this way, it marks itself as 'dirty' and 'bubbles' the notification. Parent nodes (fragments containing the view, and elements/sections etc containing those fragments) are also marked as dirty and continue propagating the notification (unless they were already dirty).

    The end result of this is that a top-level fragment is marked as dirty. Once all the data changes have been propagated, and observers etc have been called, we can 'clean' it. Because we're thinking in trees, we can disregard already-clean branches (the bits that don't need to change), and ignore any children of things that no longer need to exist.

    (Almost) no breaking changes

    I'm hopeful that the only breaking changes will be desirable ones (e.g. #1776). If there are any breaking changes as a result of this rewrite, they'll be signposted in the documentation, but so far it looks good. (About 5% of the tests are currently failing, but most of them look like they'll be remedied reasonably straightforwardly.)


    If you read this far, congratulations on your stamina. As ever, feedback and questions are warmly welcomed. Thanks!

    opened by Rich-Harris 37
  • Bump json5 from 2.1.3 to 2.2.3

    Bump json5 from 2.1.3 to 2.2.3

    Bumps json5 from 2.1.3 to 2.2.3.

    Release notes

    Sourced from json5's releases.

    v2.2.3

    v2.2.2

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

    v2.2.1

    • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)

    v2.2.0

    • New: Accurate and documented TypeScript declarations are now included. There is no need to install @types/json5. (#236, #244)
    Changelog

    Sourced from json5's changelog.

    v2.2.3 [code, diff]

    v2.2.2 [code, diff]

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

    v2.2.1 [code, diff]

    • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)

    v2.2.0 [code, diff]

    • New: Accurate and documented TypeScript declarations are now included. There is no need to install @types/json5. (#236, #244)
    Commits
    • c3a7524 2.2.3
    • 94fd06d docs: update CHANGELOG for v2.2.3
    • 3b8cebf docs(security): use GitHub security advisories
    • f0fd9e1 docs: publish a security policy
    • 6a91a05 docs(template): bug -> bug report
    • 14f8cb1 2.2.2
    • 10cc7ca docs: update CHANGELOG for v2.2.2
    • 7774c10 fix: add proto to objects and arrays
    • edde30a Readme: slight tweak to intro
    • 97286f8 Improve example in readme
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • docs: Fix a few typos

    docs: Fix a few typos

    There are small typos in:

    • qunit/qunit.js
    • src/Ractive/construct.js
    • src/view/items/Triple.js
    • src/view/items/partial/getPartialTemplate.js

    Fixes:

    • Should read suffixes rather than suffixies.
    • Should read requires rather than requireds.
    • Should read remaining rather than remainging.
    • Should read hierarchy rather than heirarchy.
    • Should read environments rather than enviroments.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 0
  • How to declare additional attribute for a partial?

    How to declare additional attribute for a partial?

    Is there a known way to declare additional attributes for a partial? For example:

    {{#partial mybutton}}
      <mycomponent foo="{{value}}" bar="{{size}}"  color="green" hello="there" /> 
      <!-- mycomponent also supports width= attribute -->
    {{/partial}}
    
    {{#with myvar1}}
      {{> mybutton}}
    {{/with}}
    
    {{#with myvar2}}
      {{> mybutton width="300"}} <- this syntax would be pretty handy
    {{/with}}
    

    I simply want to use mycomponent with some default configuration and then I want to extend it with a new attribute only for the next instance.

    opened by ceremcem 4
  • Bump decode-uri-component from 0.2.0 to 0.2.2

    Bump decode-uri-component from 0.2.0 to 0.2.2

    Bumps decode-uri-component from 0.2.0 to 0.2.2.

    Release notes

    Sourced from decode-uri-component's releases.

    v0.2.2

    • Prevent overwriting previously decoded tokens 980e0bf

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.1...v0.2.2

    v0.2.1

    • Switch to GitHub workflows 76abc93
    • Fix issue where decode throws - fixes #6 746ca5d
    • Update license (#1) 486d7e2
    • Tidelift tasks a650457
    • Meta tweaks 66e1c28

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.1

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump engine.io from 3.6.0 to 3.6.1

    Bump engine.io from 3.6.0 to 3.6.1

    Bumps engine.io from 3.6.0 to 3.6.1.

    Release notes

    Sourced from engine.io's releases.

    3.6.1

    :warning: This release contains an important security fix :warning:

    A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the Node.js process:

    Error: read ECONNRESET
        at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
    Emitted 'error' event on Socket instance at:
        at emitErrorNT (internal/streams/destroy.js:106:8)
        at emitErrorCloseNT (internal/streams/destroy.js:74:3)
        at processTicksAndRejections (internal/process/task_queues.js:80:21) {
      errno: -104,
      code: 'ECONNRESET',
      syscall: 'read'
    }
    

    Please upgrade as soon as possible.

    Bug Fixes

    • catch errors when destroying invalid upgrades (83c4071)
    Changelog

    Sourced from engine.io's changelog.

    3.6.1 (2022-11-20)

    :warning: This release contains an important security fix :warning:

    A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the Node.js process:

    Error: read ECONNRESET
        at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
    Emitted 'error' event on Socket instance at:
        at emitErrorNT (internal/streams/destroy.js:106:8)
        at emitErrorCloseNT (internal/streams/destroy.js:74:3)
        at processTicksAndRejections (internal/process/task_queues.js:80:21) {
      errno: -104,
      code: 'ECONNRESET',
      syscall: 'read'
    }
    

    Please upgrade as soon as possible.

    Bug Fixes

    • catch errors when destroying invalid upgrades (83c4071)

    6.2.1 (2022-11-20)

    :warning: This release contains an important security fix :warning:

    A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the Node.js process:

    Error: read ECONNRESET
        at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
    Emitted 'error' event on Socket instance at:
        at emitErrorNT (internal/streams/destroy.js:106:8)
        at emitErrorCloseNT (internal/streams/destroy.js:74:3)
        at processTicksAndRejections (internal/process/task_queues.js:80:21) {
      errno: -104,
      code: 'ECONNRESET',
      syscall: 'read'
    }
    

    Please upgrade as soon as possible.

    Bug Fixes

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump electron from 3.1.13 to 18.3.7

    Bump electron from 3.1.13 to 18.3.7

    Bumps electron from 3.1.13 to 18.3.7.

    Release notes

    Sourced from electron's releases.

    electron v18.3.7

    Release Notes for v18.3.7

    Fixes

    • Fixed WCO not responding to touch events on windows. #35177 (Also in 19, 20)
    • Fixed webContents.getUserAgent() incorrectly returning an empty string unless previously set. #35130 (Also in 17, 19, 20)
    • Fixed an issue in which calling setBounds() after e.preventDefault in a 'will-move' or 'will-resize' event wouldn't change the window's shape until the mouse button was released. #35082 (Also in 19, 20)
    • Fixed context menu not showing all items on macOS when dock is not hidden. #35198 (Also in 19)
    • None. #35171 (Also in 19, 20)

    Other Changes

    • Fixed page size always being restricted to 4k on Linux arm64. #35184
    • Security: backported fix for CVE-2022-2478. #35099
    • Security: backported fix for chromium:1334864. #35097

    electron v18.3.6

    Release Notes for v18.3.6

    Fixes

    • Fixed a crash when calling BrowserWindow.setEnabled(). #34973 (Also in 19, 20)
    • Fixed a potential crash when changing window settings after initializing WCO with an invalid titleBarStyle. #34873 (Also in 17, 19, 20)
    • Fixed alwaysOnTop BrowserWindow option for X11 Linux. #34911 (Also in 19, 20)
    • Fixed an issue where BrowserWindows on macOS were incorrectly marked as resizable. #34907 (Also in 19, 20)
    • Fixed an issue where Windows Control Overlay buttons did not respect maximizable/minimizable/closable states of a BrowserWindow. #34720 (Also in 17, 19, 20)
    • Fixed an issue where calling BrowserWindow.setRepresentedFilename on macOS with titlebarStyle: 'hiddenInset' or titlebarStyle: 'hidden' inadvertently moves the traffic light location. #34847 (Also in 19, 20)
    • Fixed an issue where some BrowserWindows opened from new links wouldn't properly load URLs. #34910 (Also in 19)
    • Fixed an issue where the minimize button with WCO enabled would incorrectly be highlighted in some cases. #34838 (Also in 17, 19, 20)
    • Fixed an issue with background colors being improperly applied to BrowserViews on Windows. #33478 (Also in 16)
    • Fixed empty app_id when running under wayland. #34877 (Also in 19, 20)
    • Fixed missing Sec-CH-UA headers and empty navigator.userAgentData. #34758 (Also in 17, 19, 20)
    • Fixed symbol generation on 32-bit Windows release builds. #35096 (Also in 19, 20)
    • Prevent brief display of "Ozone X11" in window title on Linux. #34943

    Other Changes

    • Backported fix for CVE-2022-2294. #34882
    • Security: backported fix for 1287804. #35102
    • Security: backported fix for 1333333. #34689
    • Security: backported fix for 1335054. #34687
    • Security: backported fix for 1335458. #34685
    • Security: backported fix for 1336014. #35004
    • Security: backported fix for 1339844. #35002
    • Security: backported fix for 1340335. #35000
    • Security: backported fix for 1340654. #34998
    • Security: backported fix for CVE-2022-2162. #34714
    • Security: backported fix for CVE-2022-2295. #34881

    electron v18.3.5

    Release Notes for v18.3.5

    ... (truncated)

    Changelog

    Sourced from electron's changelog.

    Breaking Changes

    Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least one major version before the change is made.

    Types of Breaking Changes

    This document uses the following convention to categorize breaking changes:

    • API Changed: An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
    • Behavior Changed: The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
    • Default Changed: Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
    • Deprecated: An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
    • Removed: An API or feature was removed, and is no longer supported by Electron.

    Planned Breaking API Changes (23.0)

    Removed: BrowserWindow scroll-touch-* events

    The deprecated scroll-touch-begin, scroll-touch-end and scroll-touch-edge events on BrowserWindow have been removed. Instead, use the newly available input-event event on WebContents.

    // Removed in Electron 23.0
    win.on('scroll-touch-begin', scrollTouchBegin)
    win.on('scroll-touch-edge', scrollTouchEdge)
    win.on('scroll-touch-end', scrollTouchEnd)
    

    // Replace with win.webContents.on('input-event', (_, event) => { if (event.type === 'gestureScrollBegin') { scrollTouchBegin() } else if (event.type === 'gestureScrollUpdate') { scrollTouchEdge() } else if (event.type === 'gestureScrollEnd') { scrollTouchEnd() } })

    Removed: webContents.incrementCapturerCount(stayHidden, stayAwake)

    The webContents.incrementCapturerCount(stayHidden, stayAwake) function has been removed. It is now automatically handled by webContents.capturePage when a page capture completes.

    const w = new BrowserWindow({ show: false })
    

    // Removed in Electron 23 w.webContents.incrementCapturerCount() </tr></table>

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
hell.js πŸš€ πŸš€ A JavaScript framework for the πŸ”₯ next πŸ”₯ generation. πŸš€

hell.js ?? ?? A JavaScript framework for the ?? next ?? generation. ??

null 31 Oct 3, 2022
βš›οΈ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

Fast 3kB alternative to React with the same modern API. All the power of Virtual DOM components, without the overhead: Familiar React API & patterns:

Preact 33.5k Dec 31, 2022
Aleph.js is a fullstack framework in Deno, inspired by Next.js.

Aleph.js is a fullstack framework in Deno, inspired by Next.js.

Aleph.js 5k Dec 30, 2022
Next-generation DOM manipulation

Ractive.js - Next-generation DOM manipulation Have any questions or just want to chat? Join us on GitHub Discussions! What is Ractive.js? It's a JavaS

Ractive.js 5.9k Jan 4, 2023
Frontend framework for creating reactive UIs using direct DOM manipulation. (WIP)

Cosmos Framework A frontend framework for creating reactive UIs using direct DOM manipulation. (Heavily WIP) How to get started with Cosmos Framework

CosmicMedia 5 Nov 6, 2022
A small javascript DOM manipulation library based on Jquery's syntax. Acts as a small utility library with the most common functions.

Quantdom JS Quantdom is a very small (about 600 bytes when ran through terser & gzipped) dom danipulation library that uuses a Jquery like syntax and

Sean McQuaid 7 Aug 16, 2022
An app to manage tasks. A user can add, delete and edit a task and mark it as completed, It uses simple GUI and relies on DOM manipulation in pure JS and using local storage.

An app to manage tasks. A user can add, delete and edit a task and mark it as completed, It uses simple GUI and relies on DOM manipulation in pure JS and using local storage.

KHITER Mohamed Achraf 6 Aug 20, 2022
Custom Vitest matchers to test the state of the DOM, forked from jest-dom.

vitest-dom Custom Vitest matchers to test the state of the DOM This library is a fork of @testing-library/jest-dom. It shares that library's implement

Chance Strickland 14 Dec 16, 2022
An extension of DOM-testing-library to provide hooks into the shadow dom

Why? Currently, DOM-testing-library does not support checking shadow roots for elements. This can be troublesome when you're looking for something wit

Konnor Rogers 28 Dec 13, 2022
A next-generation package manager for the front-end

Duo is a next-generation package manager that blends the best ideas from Component, Browserify and Go to make organizing and writing front-end code qu

Duo 3.4k Dec 28, 2022
Next generation frontend tooling. It's fast!

Vite ⚑ Next Generation Frontend Tooling ?? Instant Server Start ⚑️ Lightning Fast HMR ??️ Rich Features ?? Optimized Build ?? Universal Plugin Interfa

vite 51.2k Jan 5, 2023
The next generation Javascript WYSIWYG HTML Editor.

Froala Editor V3 Froala WYSIWYG HTML Editor is one of the most powerful JavaScript rich text editors ever. Slim - only add the plugins that you need (

Froala 5k Jan 1, 2023
🐠 Babel is a compiler for writing next generation JavaScript.

The compiler for writing next generation JavaScript. Supporting Babel Babel (pronounced "babble") is a community-driven project used by many companies

Babel 41.8k Jan 9, 2023
A next-generation code testing stack for JavaScript.

Intern Software testing for humans ⚠️ This documentation is for the development version of Intern. For the current release version, go here. Intern is

Intern: next-gen JavaScript testing 4.4k Jan 7, 2023
Next-generation ES module bundler

Rollup Overview Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a librar

Rollup 22.7k Jan 4, 2023
Next-generation ES module bundler

Rollup Overview Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a librar

Rollup 22.7k Jan 4, 2023
πŸŽ‰ Next Generation API-first CMS for developers. Generate an API-first CMS from a GraphQL schema with offline prototyping and an inline editor

Tipe Next Generation API-first CMS Design your content Shape and design content for any project you and your team are working on. Create your content

Tipe 2.2k Oct 22, 2021
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server & SQLite

Prisma Quickstart β€’ Website β€’ Docs β€’ Examples β€’ Blog β€’ Slack β€’ Twitter β€’ Prisma 1 What is Prisma? Prisma is a next-generation ORM that consists of the

Prisma 28k Jan 2, 2023