Git Product home page Git Product logo

jsonml's Introduction

Build Status

This is an implementation of JsonML in Dart.

JsonML is useful whenever you are sending HTML to the client from a server (or from an Isolate). Instead of sending the HTML string (which needs to be parsed and, ideally, sanitized), you are sending a lossless representation of it in JSON format.

This is how a simple paragraph looks like in JsonML:

["p", 
  {"class": "example"},
  "This paragraph is ",
  ["em",
    "all"
  ],
  " about ",
  ["a",
    {"href": "http://www.jsonml.org/"},
    "JsonML"
  ],
  "."
]

The object above would be rendered as:

This paragraph is all about JsonML.

Advantages over HTML:

  1. It's sent as JSON, and therefore it is relatively inexpensive to parse.
  2. It can exist in the memory as a simple Dart/JavaScript object --- no special class structure needed.
  3. It's a list (array) of nodes, and so it's pre-formatted for fast DOM building on the client side.

For more information about the format, including formal specs and examples of use, read the official JsonML site.

Example

Note: See examples in example/ to get the full picture.

import "package:jsonml/html2jsonml.dart";

var jsonml = encodeToJsonML("<h1>Title</h1><p>First paragraph.</p><p>Second paragraph.</p>");

The object can be then stringified by calling JSON.encode() of the standard dart:convert library.

In the browser, here is how one can append the contents of the JsonML object to a DOM element.

import "package:jsonml/jsonml2dom.dart";

var node = decodeToDom(jsonml, unsafe: true);
querySelector("#destination").append(node);

The decodeToDom function takes an Object. For convenience, one can also use decodeStringToDom, which takes a String (which it then decodes using the standard JSON library).

Note the unsafe: true optional attribute. When the unsafe optional argument is true, the JsonML object will be copied to the DOM verbatim, including potentially insecure tags like <script> and attributes like href. In safe mode (unsafe == false) the potentially dangerous content would be stripped before creating the DOM nodes. This is not implemented yet, so the user must currently always specify unsafe: true. This ensures that the unsafeness is explicit in the code.

Security

The library currently doesn't employ any stripping of potentially unsecure tags and attributes. This is made explicit by forcing the user to provide the optional argument unsafe: true. As ironic as it sounds (forcing an optional argument), it's there for a reason. No user content should ever be sent to DOM via jsonml2dom.

In the future, when unsafe == false, the library will take care of stripping anything that could be malicious (in the same way as the Dart standard library's innerHtml does already). This isn't yet implemented.

Speed

The repo contains a benchmark harness. It measures the speed with which the browser can go from a String representation of the DOM to the actual elements, and compares HTML+innerHtml with JsonML+this library.

Not surprisingly, JsonML fares better in terms of speed than HTML. In my limited testing, it seems that shorter structured text can easily be twice as fast (Chrome 2.8x) to parse and render with JsonML than with innerHtml. With longer and less structured text, the performance gain diminishes but is still significant. Parsing and rendering of a longer article is a good 70% faster (Chrome 1.7x).

Even more performance is gained by skipping String parsing. This is not doable with HTML (there is no non-string representation of HTML in Dart/JavaScript), but easy with JsonML (JsonML object is just a list of lists, maps and strings). When working with JsonML objects (List) instead of JsonML strings, the library can easily be 3 times faster than innerHtml.

The speed of encoding from HTML to JsonML is not measured (at the moment) since performance there doesn't tend to be an issue (this is normally executed only once and on the server, not on clients).

TODO

  • dom2jsonml for sending page structure back to the server (for example when user can edit DOM elements)
  • safe mode (see above)

History

As an aside: this project started as "HSON" (HTML over JSON) before I realized this idea can't be original โ€” and of course it wasn't. The original "HSON" format was a bit less verbose, but that was its only advantage. It was also much less flexible and portable, and made less sense in general. The moral of this story: whenever you have an idea, start with searching the net.

jsonml's People

Contributors

filiph avatar allingaming avatar

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.