jsonml 0.1.8+1

  • README.md
  • Installing
  • Versions
  • 46

#JsonML for Dart

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.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  jsonml: ^0.1.8+1

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:jsonml/html2jsonml.dart';
import 'package:jsonml/html5lib2jsonml.dart';
import 'package:jsonml/jsonml2dom.dart';
import 'package:jsonml/jsonml2html5lib.dart';
  
Version Uploaded Documentation Archive
0.1.8+1 Jul 24, 2018 Go to the documentation of jsonml 0.1.8+1 Download jsonml 0.1.8+1 archive
0.1.8 Jul 24, 2018 Go to the documentation of jsonml 0.1.8 Download jsonml 0.1.8 archive
0.1.7 Nov 12, 2014 Go to the documentation of jsonml 0.1.7 Download jsonml 0.1.7 archive
0.1.6 Nov 12, 2014 Go to the documentation of jsonml 0.1.6 Download jsonml 0.1.6 archive
0.1.5 May 18, 2014 Go to the documentation of jsonml 0.1.5 Download jsonml 0.1.5 archive
0.1.4 May 18, 2014 Go to the documentation of jsonml 0.1.4 Download jsonml 0.1.4 archive
0.1.3 Apr 30, 2014 Go to the documentation of jsonml 0.1.3 Download jsonml 0.1.3 archive
0.1.2 Apr 30, 2014 Go to the documentation of jsonml 0.1.2 Download jsonml 0.1.2 archive
0.1.1 Apr 29, 2014 Go to the documentation of jsonml 0.1.1 Download jsonml 0.1.1 archive
0.1.0 Apr 29, 2014 Go to the documentation of jsonml 0.1.0 Download jsonml 0.1.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
46
Learn more about scoring.

We analyzed this package on Aug 10, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.11.8

Platforms

Detected platforms: web

Platform components identified in package: html.

Issues and suggestions

Maintain CHANGELOG.md.

Changelog entries help clients to follow the progress in your code.

Package is pre-v1 release.

While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction of the API.

Maintain an example.

None of the files in your example/ directory matches a known example patterns. Common file name patterns include: main.dart, example.dart or you could also use jsonml.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.69.0 <3.0.0
html >=0.13.3+2 <0.14.0 0.13.3+2
Transitive dependencies
args 1.5.0
charcode 1.1.2
csslib 0.14.4+1
logging 0.11.3+2
path 1.6.2
source_span 1.4.1
utf 0.9.0+5
Dev dependencies
benchmark_harness ^1.0.4
build_runner >=0.8.10 <0.10.0
build_web_compilers >=0.3.6 <0.5.0
test ^1.3.0