Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@plotdb/block

plotdb157MIT5.5.4

block

readme

@plotdb/block

Frontend module manipulation library with following features:

  • HTML-based module definition
  • scoped JS / CSS for vanilla libraries with no bundling required.
  • reuseable, extendable components

Usage

install @plotdb/block along with all necessary js libraries:

npm install @plotdb/block @plotdb/rescope @plotdb/csscope @plotdb/semver proxise

and include them:

<script src="path-to-semver/index.min.js"></script>
<script src="path-to-proxise/index.min.js"></script>
<script src="path-to-csscope/index.min.js"></script>
<script src="path-to-rescope/index.min.js"></script>
<script src="path-to-block/index.min.js"></script>

Load a sample block:

mgr = new block.manager(...);
mgr.from({name: 'block name', version: 'x.y.z', path: "index.html"})
  .then ({instance, interface}) -> ...

A sample block may look like this:

<div>
  <script type="@plotdb/block">
    module.exports = {};
  </script>
  <h1>
    hello world!
  </h1>
</div>

Concept

Similar to web component, @plotdb/block modularizes frontend codes into components called block. A block is defined with a plain HTML file, containing following 3 parts ( all parts are optional ):

  • HTML
  • CSS
  • JavaScript

This is an example of a block file:

<div>
  <h1> Hello World! </h1>
  <style> /* plain CSS ... */ </style>
  <script type="@plotdb/block"> /* plain javascript ... */ </script>
</div>

Since it's just a valid HTML file, User can use different languages ( Sass, TypeScript, Pug, etc ) and transpile when necessary, once the result file is a plain HTML file.

Following is an example with Pug, LiveScript and Stylus with additional Pug filters ( :stylus and :lsc ) which can be transpiled directly with srcbuild-pug command provided in @plotdb/srcbuild:

div
  h1 Hello World!
  style: :stylus
    h1 { color: #543; }
  script(type="@plotdb/block"): :lsc
    module.export = { init: -> console.log \loaded. };

Script can either be an object described as below, or a function returning that object. Styles will be automatically scoped and limited in this block.

Block Identifier (BID) and File Accessing

To use a block, we need to know how to identify it. This is called Block IDentifier (BID). Like npm modules, blocks are defined with name, version and an optional ns, where:

  • ns: Namespace, such as npm or github. How this works depends on how registry is implemented.
  • name: Block name. Use the naming convention as npm. e.g., @loadingio/spinner
  • version: Block version in semver format, or labels such as main, latest.

Additionally, files in a block are identified with path and `type fields:

  • path: path of the block definition file inside the module name@version.
    • if omitted, inferred by type field, or decided by block manager.
  • type: type of the requested file. if omitted, inferred from path, or decided by block manager.

For extensibility, additional fields can be used for specified purposes, which won't be used by @plotdb/block:

  • parts: for defining a set of related bids. additional bids are stored as members under this object in bid object format; their fields are optional and fallback to the base bird if omitted. For example:

    { ns: "local", name: "mybid", parts: {

     "reader": { path: "reader.html" }, /* its `ns` and `name` will fallback to `local` and `mybid` */
     "writer": { path: "reader.html" }

    } }

    parts field is standardized solely to unify related usage. @plotdb/block doesn't include code to actually handle it.

  • opt: Optional customized data goes here. Use it for any custom fields to be stored in bid if needed.

This block identifier can either be an object or a string, such as this object:

{ns: "local", name: "@plotdb/konfig", version: "1.2.3", path: "index.html"}

with a identical string representation:

local:@plotdb/konfig@1.2.3:index.html

@plotdb/block provides two methods to convert between string and object identifier:

  • block.id(obj): return the corresponding string representation of an identifier object obj.
    • see below for more options.
  • block.id2obj(id): return the corresponding object represetnation of an string identifier id.

To access a block file identified by a block identifier, we can use block.manager:

manager = new block.manager({
  /* indicating where we can find the file */
  registry: ({ns,name,version,path}) -> "/block/#name/#version/#path/index.html"
});
mananger.init!
  .then -> manager.get({name: "my-block", version: "0.1.0"})
  .then (blockClass) -> ...

Manager, Class and Instance of Block

The resolved object from manager.get is a instance of block.class, which represents the definition of the given block file. To use it, we have to create an instance of block.instance from it, such as:

manager.get( ... )
  .then (cls) -> cls.create();
  .then (instace) -> ...

A block instance can then be injected into web page:

instance.attach({root: document.body})
  .then -> ...

Below is a simplified flow of relationship between the above concepts:

  • block file (in HTML)
  • block.manager: load, convert and cache block files.
  • block.class: Object representation of a block file.
  • block.instance: a JS Instance created from block.class

Core modules

As described above, @plotdb/block contains following basic elements:

  • block.manager - to access, register, get and cache block.class
  • block.class - representing the definition of a block, and is used to generate block.instance.
  • block.instance - object for manipulating state / DOM of a given block.

Additionally, block itself provides following functions:

  • block.id(obj) - return an ID corresponding to input object with following possible fields:
    • id: if id exists, it will be returned directly.
    • url: if id is not found abut url exists, url will be returned instead.
    • ns, name, version, path: if none of above is found, use these to generate an ID.
      • name is required in this case.
      • version default to main, path default to index.html if not provided.
  • block.id2obj(id) - reversely convert id into block with ns, name, version and path fields.
  • block.i18n

    • use(obj): use obj to replace module.
    • language: current used language.
    • changeLanguage and addResourceBundle: see below in module.
      • TODO we may want to remove these, and rely on module directly.
    • module: default i18n module object, which should support following APIs:
      • t(..): return translated text based on given input.
      • on(name, cb): listen to event name with listener cb. expected events:
        • languageChanged: fired when language changes.
      • off(name, cb): remove listener cb from event name.
      • changeLangauge(ns): set default language to ns.
      • addResourceBundle(...): add resource bundle, with following parameters ( in order ):
        • lng: ns for this resource to add.
        • id: id if any. default undefined.
        • resource: resource to add
        • deep: default true.
        • overwrite: default true. whether overwrite existing resource or not.
  • block.env(win) - set current environment to win.

block.manager

Since a block is just a plain HTML, it can be stored anywhere once a string can be stored. Common places to store a block may be:

  • local in web page: block HTMLs are served directly along the web page.
  • remote in web server: block HTMLs are stored as files and can be accessed via Ajax through specific URL.

either way we have to provide a way to load, register, cache these blocks - that is, to manage them, which can be done with the help of block.manager.

constructor options

Create a block.manager instance with

mgr = new block.manager(opt);

where the constructor options are as below:

  • registry: either function or string, tell block.manager where to find remote blocks.

    • function({ns,url,name,version,path,type}): return URL for given bid of a block.
      • should respect url or use/transofmr it if provided.
    • string: the registry base url. block.manager will look up blocks under this url with this rule:
      • /assets/block/<name>/<version>/<path>
    • object:

      • either an object with url and fetch (optional) field, or lib and block field.

        • url and fetch:
          • url({ns,url,name, ...}) will be used to transform given bid to an URL.
          • fetch({ns,url,...})) will be used to fetch url or bid ir provided.
            • if url() is provided, bid will be transformed first.
        • lib and block:

          • registry set here will be used for both block and libraries. To distinquish them, use:

            registry: {lib: (-> ...), block: (-> ...)}

          • registry.lib will be used for querying block if registry.block is omitted.

  • rescope: optional. should be a @plotdb/rescope object if provided.

    • will replace internal rescope object if provided.
  • csscope: optional. should be a @plotdb/csscope object if provied.
    • will replace internal csscope object if provided.
  • chain: optional. fallback manager for chaining block lookup if requested block is not found in current manager.

APIs

A block.manager instance provides following methods:

  • registry(v): update registry dynamically.
    • v: can be a function, string or an object, similar to the option in constructor.
  • set({ns,name,version,path,block}): register a block withns,name,versionandpath`.
    • block: a block-class object, explained below.
    • set also accepts Array of {name,version,block} object for batching set.
  • getUrl({ns,name,version,path}): get url for a block corresponding to the given block identifier.
  • get({ns,name,version,path,force,ctx}): return a block-class object corresponding to the given block identifier.
    • force: by default, block.manager caches result. set force to true to force block.manager re-fetch data.
    • ctx: optional context object for providing context for the requested block class.
      • note: class context is initialized when init() is called, which means that once a class is inited, new ctx provided for manager.get won't work as expected. To re-initialize, set force to true.
    • get also accept an array of {ns,name,version,path,force} tuples for batching get.
      • in this case, get returns an array of block.class.
  • from(block-id-obj, attach-opt): shorthand for manager.get + class.create + instance.attach + instace.interface
    • return a Promise which resolves to an object {interface, instance}:
      • instance: created instance
      • interface: created interface
    • block-id-obj: block identifier object. see get() and above description.
    • attach-opt: attach options. see block.instance's attach() function.
  • chain(mgr, opt): set a fallback manager for chaining lookup of requested block.
    • given mgr will be append to the end of the chain if there are already fallback managers.
    • opt is an object with following fields as parameters:
      • replace: default false. replace the current chain head with the given mgr if true.
  • rescope: rescope object, either global one or customized one.
  • csscope: csscope object, either global one or customized one.
  • id: shortcut for block.id
  • id2obj: shortcut for block.id2obj

block.class

block.class is for generating block instances. It parses the code of a block based on the block specification and convert them into clonable code, preparing for generating block.instance objects on demand.

We usually don't have to create a block.class instance manually since block.manager does this for us, however to manually create one:

cls = new block.class( ... );

constructor options

  • manager: default block manager for this class. mandatory
  • name: block name. mandatory.
  • version: block version. mandatory.
  • path: block path. optional. index.html if omitted.
  • code: use to create DOM / style / internal object. it can be one of following:
    • a function. should return either html code or object; returned value will be parsed by corresponding rules.
    • a string, providing HTML code. structure of HTML should follow the definition of a block.
    • an object, containing dom, style and script members.
      • dom: HTML code string, or a function returning HTML code string.
      • style: should be string for CSS.
      • script: function, object or string of code, for interface of the internal object by:
        • function: return the interface.
        • object: as the interface.
        • string: evaled to the interface, or a function which return the interface.
        • for detail of the "interface", see "interface of the internal object" section below.
  • root: optional. root of a DOM tree representing the block HTML code. Overwrite code.
  • ctx: optional context object, providing additional preloaded dependencies for this class.

APIs

  • create(opt): create a block.instance based on this object. options:
    • data: instance data. defined by user and passed directly to block instance javascript.
    • root and before: parameters passed to attach.
      • instance will and only will be attached automatically if root is provided.
  • context(): get library context corresponding to this block.
  • i18n(text): return translated text based on the current context.

Additional, here are the private members:

  • name: name of this block.
  • version: version of this block.
  • path: path of this block.
  • manager: block manager to use when resolving recursive blocks.
  • dom: block DOM tree.
  • scope: unique id randomly generated each time when block.class is created mainly for scoping purpose.
  • opt: raw constructor options.
  • code: source code for constructing this block.
  • script: source code for this block's script definition.
  • style: source code for this block's style definition.
  • link: reserved for future use.
  • styleNode: node storing parsed / scoped style of this block.
  • interface: javascript interface for this block.
    • This will also be used as prototype of the instance object, created by factory method below.
  • factory: constructor for generating the js context for block script. See below.
  • id: unique name for this block.
    • "name@version/path" or randomly generated one if name and version is not available.
  • \_ctx: js context object from rescope.
  • csscopes
    • local: scope list of css for local scope.
    • global: scope list of css scope name for global scope.
  • extend: extended block, as a block.class object.
  • extendDom: to extend dom or not.
  • extends: array of extended blocks. extends[0] is the direct parent class.

To create an instance from a block.class:

instance = aBlockClass.create();

While block.class is used to create instance of block.instance, JavaScript of a block will be executed when a block class is loaded, in order to prepare for upcoming instance creation. No instance context at this time since we only have the block.class object.

To access block.instance context, block JavaScript should be implemented based on the factory interface described in the following section. This will be discussed in following section JS context of block instance.

block.instance

block.instance is an instance of block created from a block.class. It's responsible for maintaining block's state and DOM status.

constructor options

  • block: block.class for this instance.
  • name, ns, version, path: as defined in the object identifier.
  • data: custom data for this instance. usage and spec of this data is defined by the block file.

APIs

  • attach({root, before, data, host, autoTransform, i18n}): attach DOM and initialize this instance.
    • block instance is attahed to root before before if before is provided.
    • if a factory interface is exported by block JS, it will be used to create an internal context and be inited.
      • see Internal JS context of a block below.
    • return a Promise which resolves with a list of internal object based on inheriance hierarchy after inited.
    • when root is omitted, attach block in headless mode ( for pure script )
    • attach DOM by appendChild when before is omitted, and by insertBefore otherwise.
    • autoTransform: default null. set to i18n to enable auto i18n transformation based on i18n module event.
      • note: will be by default i18n in future release. explicitly set to null if that's what you want.
    • i18n: customized i18n module for this block instance. optional.
      • by default, all instances use their corresponding classes' i18n api, which in turns use the one from block.i18n, and this usually is a global i18n module. this i18n option provides a mechanism to use a different i18n module for this instance.
    • host: context object provided by caller.
      • based on how pkg.host is set, it can be an object or an array of such object.
      • see Host Context section for more detail.
  • detach(): detach DOM. return Promise.
  • i18n(text): return translated text based on the current context.
  • path(p): return url for the given path p
  • dom(): return DOM corresponding to this block. Create a new one if not yet created.
  • run({node,type}): execute type API provided by block implementation with node as root.
  • transform(cfg): (re)transform DOM based on the given cfg option, which is:
    • string: name of the transform (e.g., i18n) to apply.
  • update(ops): (TBD) update datadom based on provided ops ( array of operational transformation ).

Additionally, following are the private members:

  • obj - list of JS internal context objects created from the exported factory interface.
    • see below for the detail of the internal context object.
    • it's a list of all objects from the inheritant chain. base block comes first.
    • each item in this list contains block's data and interface.

Host Context

While user can define how a block should interact with the caller by data attribute, data is meant to be defined by the block, or, at least by the block and its host.

This can sometimes be confusing in container/plugin scenario, in which blocks are designed to communicate with its container, yet container can't distinguish if a certain block is implemented based on the interface provide by this container.

Thus, we need a method to identify this container/plugin relationship.

For this purpose, an additional field host is introduced in pkg and init parameter:

{
    pkg: {host: {name: "...", version: "...", ...}},
    init: ({host, data, manager, ...}) ->
    ...
}

And block caller should provide its host:

someclass.from(
    { name: "...", ... },
    { host: {bid: "mypkg", interface: (-> ...)}, ... }
)

As shown as above, users are responsible for providing the host object. A host object should be either a block instance or an Array of such object; for simplicity, a duck typed object with following fields can be used:

  • bid: a string representing the block identifier of this host.
  • ns, name, version, path: block identifier for this given host. ignored if bid is provided.
  • interface: a function that returns the interface defined solely by the block identified by bid.

Hosts users provided will be in turn provided to host parameter of block instance's init function with following rules:

  • when pkg.host is not defined, all available hosts are provided as an array.
  • when pkg.host is a block identifier object, either an object matching that bid or a dummy object with interface function is provided.
  • when pkg.host is a list of bid, all matched hosts are provided as specified order in an array.

Internal JS Context of a block

While block.instance represents the block instance itself, block JavaScript is run in a different context to prevent intervention. The interface of this context is as below:

  • \_class: the object of block.class for this block, filled automatically when creating this context.
  • \_instance: the object of block.instance for this block, filled automatically when creating this context.
    • Note: currently this is not available in base blocks. use it only for dev / debug purpose.
  • pkg: block information
  • init(opt): initialization function of this context.
  • destroy(opt): destroy function of this context.
  • interface(): JS interface for block users to access.
  • parent: JS Context of parent block, if any.
    • use parent.interface() to reach parent interface if needed.

Except \_class and \_instance, functions in above interface should be implemented by block JavaScript and exported via module.exports:

module.exports = {
  init: (opt) ->
  interface: ->
};

This interface is used in the factory constructor of block.class to create the internal JS Context:

context = new aBlockClass.factory(instance);

which is the object stored in obj member of block.instance described in the block.instance section.

The detail of the fields of interface is as below:

  • pkg: block information, described below. optional.
  • init(opt): initializing a block. optional.

    • return a Promise for asynchronous initialization.
    • opt is an object with following fields:

      • root: root element
      • ctx: dependencies in an object.
      • context: deprecated, use ctx instead.
      • parent: object for the direct base block.
      • pubsub: for communication between block in extend chain. pubsub is an object with following methods:
        • on(event, cb(parmas)): handle event with cb callback, params from fire.
          • return value will be passed and resolved to the returned promise of fire.
        • fire(event, params): fireevent`. return promise.
      • data: data passed to create. optional and up to user.
      • host: host object passed to create. optional and up to caller.
      • path(p): path transformer to convert p to a local string based on the identifier of this block.
      • t(text): translation function based on local, base class and global i18n information. shorthand of i18n.t.
      • i18n: i18n related helpers including:

        • getLanguage()`: return current used language.
        • t(text): as described above.
        • addResourceBundles(res): dynamically adding i18n resources. sample res:

          { "zh-TW": {"string", "文字"}, "en-US": {"string": "string"} }

  • destroy({root, context}): destroying a block. optional.

  • interface: for accessing custom object. optional.
    • either a function returning interface object, or the interface object itself.
    • child block always overwrite parents' interface in an inheritance chain, if available
  • mod: reserved for block javascript. future implement update of @plotdb/block should not use it.
  • exports(global): (TBD) for sharing block as a JS library. return objects to export. optional
    • user can use a block as a library by adding it in the dependencies config, such as:
      • [{name: "some-block", version: "some-vesion", path: "path-to-file"}, ...]

All members are optional thus the minimal definition will be an empty object or even undefined:

{}

Use module.exports to explicitly export the desired object:

module.exports = { .... };

Block Information

The pkg field of a block interface is defined as:

  • ns, name, version, path: from this block's identifier. optional
  • author: author name. optional
  • license: License. optional.
  • description: description of this block. optional
  • syncInit: default false.
    • if true, each init in extend chain runs only after the returned Promise of the previous method resolves.
    • otherwise, order of init methods are not guaranteed.
  • extend: optional. block identifier of block to extend.
    • ns, name, version, path: from parent block's identifier. optional
    • dom: default true. can be any of following:
      • true: use parent's DOM if set true.
      • false: completely ignore extended DOM in any ancestor.
      • "overwrite": overwrite parent DOM but extend DOM from grantparent, if any.
    • style: default true. can be any of following:
      • true: use parent's style if set true.
      • false: completely ignore extended style in any ancestor.
      • "overwrite": overwrite parent style but extend style from grantparent, if any.
    • use plug ( for html ), parent and pubsub ( js ) to work with extended block.
      • for more information about plug, see HTML Plugs section below.
  • host: optional. block identifier of host block it supports.
    • can be either an object of bid or an array of such object.
  • dependencies: dependencies of this block.
    • list or modules, in case of mutual dependencies: ["some-url", {url: "some-url", async: false, dev: true, global: true, type: "css, js or block"}]
    • for now, block type dependencies are used for hint of bundling.
    • options in object notation:
      • `async: true to load this module asynchronously. true by default.
      • `global: for CSS. true if the CSS should also work in global scope. ( under body ). default false.
      • type: default js. either css or js.
        • (TBD) support block type for preloading block / export block library.
      • url: path of required module.
        • generated from name + version + path if omitted. ( TODO )
      • name: name of required module ( TODO )
      • version: version of required module ( TODO )
      • mode: use to control when this module should be loaded. ( TODO )
    • dependencies will be additive in inheritance chain.
  • i18n: i18next style i18n resource. e.g.,

    { "zh-TW": { "name": "名字" } }

Block Events

(TBD) Following are possible events:

  • before insert
  • init
  • after insert
  • before destroy
  • destroy
  • after destroy
  • update

i18n configuration

use block.i18n.use(...) to switch the core i18n module, which should at least implement following API:

  • addResourceBundle(lng, ns, resource, deep, overwrite)
  • changeLanguage(lng)
  • t(text)

These API are intentionally aligned with i18next. Check i18next documentation for more information about these API.

A sample setup with i18next and @plotdb/block:

i18next.init({supportedLng: ["en", "zh-TW"], fallbackLng: "en"})
  .then(function() { i18next.changeLanguage("zh-TW"); })
  .then(function() { block.i18n.use(i18next); })

HTML Plugs

Base block may provide slots for child block to plug. use <plug> tag with name attribute:

<plug name="layout"/>

To plug elements In child block to given slot, use plug attribute in child block:

<div plug="layout"> ... </div>

Note: slots without plugs will be converted to <div> node.

You can also create a block instance under a root with predefined plugs to inject custom nodes into a block without extending it:

<div ld="root"><div plug="name"> Hello </div></div>
<script>
  manager.from({name: "myblock"}, {root: document.querySelector('[ld=root]')})
</script>

Packed Block with Bundled Packages

To ship bundled packages along with a block, simply append the corresponding <template> tag at the end of the block:

<div> ... </div><template rel="block"> ... </template>

Actually, any template tag in this block with rel attribute set to block will be considered a bundle tag for @plotdb/block.

Why block

At first we just want to make web editing easier across expertise, and block design ( see future of web design comes in blocks, Editor.js ) seems to be a trend in web design. It's similar to web components but we will have to do more for making visually editing possible.

While what @plotdb/block ( web component & management ) provides is already available in other popular frameworks, @plotdb/block is actually designed with following criteria thus makes it different with others:

  • version management
    • blocks are managed with proper versioning.
    • blocks should work even using the same lib with different versions without import.
      • popular frameworks use import which will have to bundle js within.
      • even if bundle is not necessary, many libs don't support import and will need wrapper.
  • framework agnostic
    • prevent from abducted by specific framework
    • while we seem to invent yet another framework:
      • @plotdb/block is only for components. no state management, no reactive.
      • thus, any js frameworks are expected to work well with @plotdb/block.
  • As Simple as Possible
    • making a component is extremely easy. ( KISS principle )
      • there is no new syntax to learn in @plotdb/block, only interface.
  • Collaborative
    • @plotdb/block is built along with @plotdb/datadom for DOM serialization.
      • this makes it by default suitable for serialization, thus also for collaboration
      • editing can be described by concepts such as operational transformation
  • DOM manipulating with UI ( cross expertise editing )
    • this is covered in @plotdb/editable.

Resources

  • Related modules
    • editable: cross-expertise editor interface based on a set of predefined attributes over plain HTML.
    • datadom: DOM in JSON, with extension.
    • registry: block module storage and delivery.

License

MIT

changelog

Change Logs

v5.5.4

  • fix bug: host should always be inited and checked for existence before using

v5.5.3

  • add event handler / language getter in i18n interface provided to block instance when initializing

v5.5.2

  • apply fallback default plug after matching child plug to support nested plug

v5.5.1

  • use div to replace plug node if a slot is not replaced.

v5.5.0

  • add host mechanism to support container/plugin model with declarative approach.

v5.4.4

  • let block.id return the given parameter directly if it's a string.

v5.4.3

  • fix bug: ns isn't available in block.class even if given in block pkg information.
  • add a new field host representing host (caller) context (experimental)
  • fix bug: missing n in i18n in add-resource-bundles in interface for block instance.

v5.4.2

  • fix bug: fetch should check return value of _ref again null before testing its then member.

v5.4.1

  • append given manager in chain tail instead of replacing current chain.
  • extend chain api to support replace option.

v5.4.0

  • support customized i18n object in block.instance.
  • enable access to language in fallback 1i8n module

v5.3.1

  • escape colon ":" in i18n token to prevent from been treated incorrectly as key separatoor

v5.3.0

  • support ctx option in block.manager.get and block.class constructor to share caller context with classes.

v5.2.5

  • support syncInit option in pkg which enable synchronous init call in extend chain.

v5.2.4

  • remove index.html from bundle key and proxy hash key to prevent potential key duplication
  • when bundling, check if the given path is a directory and add index.html to try again if it is.
  • support debundling of multiple bundles parallelly.

v5.2.3

  • fix bug: incorrect result from internal i18n translator with empty string

v5.2.2

  • fix bug: bundler incorrect ignores http protocol

v5.2.1

  • fix bug: default i18n translator may access fields null objects accidentally

v5.2.0

  • support debundling from packed block with bundle packages.

v5.1.0

  • support autoTransform in instance.attach. expected to be default i18n in future upgrade.
  • add event handling mechanism in block.i18n.module with an expected event languageChanged.

v5.0.8

  • update @plotdb/rescope dependency version to 5.0.6

v5.0.7

  • upgrade peerDependencies and dependencies

v5.0.6

  • fix bug: block.i18n should keep the original text t to return if translation is not found.

v5.0.5

  • fix bug: fallback i18n transformer doesn't support keySeparator

v5.0.4

  • init parent field of internal context object right at initialization.
  • fix bug: i18n api should also accept the interpolation object.

v5.0.3

  • fix bug: will try using fs once defined even in browser.

v5.0.2

  • fix bug: _ref pollutes the input bid.
  • upgrade peer dependencies rescope and csscope

v5.0.1

  • upgrade peer dependencies rescope and csscope

v5.0.0

  • fix bug: id() should generate path depending on the type in bid.
  • fix bug: document should be doc in debundler
  • support bundling of block type files.
  • registry should not return Promise now, and should consider url parameter now.
  • registry.fetch accepts and should consider url from registry.url now.
  • remove undocumented fetch option.
  • fix bug: 2 Promise.rejects are wrapped when fetch fails, and thus one of them is always uncaught
  • add rel="block" in the bundled template

v4.8.0

  • fix bug: bundle should not modify input list
  • breaking change of dev feature: return block dependencies and code in bundle
  • fix bug: remove code from dummy depcss-cache to eliminate redundant bundling

v4.7.10

  • fix bug: debundle nothing injects text undefined in document.
  • by default don't display the debundle container
  • upgrade package to fix vulnerability in dependency

v4.7.9

  • fix bug: paths in block css are not transformed correctly when debundling

v4.7.8

  • fix bug: debundle of nothing should not fail

v4.7.7

  • properly scope script

v4.7.6

  • fix bug: css path transformation should not work on data url
  • replace unnecessary parse-name-string with id2obj
  • fix bug: ns omitted in block id inheritance
  • use error generator function to generate errors
  • restructure code for node / browser and bundler
  • upgrade dependencies

v4.7.5

  • fix bug: incorrect loop index when getting interface from instance
  • support interface retrieval recursively
  • provide parent directly in internal js context object
  • provide _instance object only if the corresponding class matches.
  • remove update function since it's in TBD state

v4.7.4

  • fix bug: inferred block feature should not work on identifier with only url field.

v4.7.3

  • rewrite buggy circular extend detection code

v4.7.2

  • throw exception when circular extend detected
  • remove useless code

v4.7.1

  • make bundle.js a clone of index.js with bundle function

v4.7.0

  • upgrade modules
  • separate bundle method into standalone file
  • support inferred block name / version

v4.6.2

  • also consider ns in block.id

v4.6.1

  • audit fix for vulnerabilities fixing
  • bug fix: fix typo from console.log warn to console.warn

v4.6.0

  • pass path into instance.
  • support defer in attach
  • support language in block.i18n
  • support getLanguage in i18n object passed to block js

v4.5.4

  • bug fix: id-to-obj should be id2obj in debundle function.

v4.5.3

  • bug fix: transformation cross block boundary leads unexpected i18n result.

v4.5.2

  • bug fix: i18n transformation doesn't propagate correctly through base blocks.

v4.5.1

  • fix bug: from failed due to incorrect code parsing.

v4.5.0

  • add manager.from support, shorthand for block instance generation
  • extend block.create function with additional root option for directly attaching

v4.4.0

  • downgrade node-fetch back to v2.6.7 to make it work in nodejs
  • add id2obj function
  • bug fix: id2obj parsing may be wrong due to ns
  • add id2obj test

v4.3.0

  • provide a method for generating id based on input object.
  • add ns ( namespace ) support in block definition. ns defaults to

v4.2.0

  • bug fix: remove accidentally added log
  • support path translation in HTML with path and path-* attribute.
  • support path translation in JS with path function.
  • support path translation in style.

v4.1.2

  • bug fix: translation of non-string value may fail.
    • convert value for translation to string to error in prevent i18n module
  • support dom interpolation from container content

v4.1.1

  • fix bug: i18n doesn't work due to colon in id. use an alternative _id_t without colon for i18n scope.

v4.1.0

  • default empty in version when building id
  • support semantic versioning with ranges.
  • support custom registry that return content + version directly.
  • use minimized dist file as main / browser default file
  • remove livescript header in generated js
  • upgrade modules
  • patch test code to make it work with upgraded modules
  • remove assets files from git
  • release with compact directory structure

v4.0.1

  • upgrade @plotdb/csscope and @plotdb/rescope dependencies
  • add manager in payload for block script to use for recursive block loading

v4.0.0

  • a module object is provided to block js, which can be used to export block defition.
  • dedup blocks in bundler
  • fix typo in id generation

v3.0.3

  • properly wrap js code in bundler to prevent from syntax error
  • still provide cache information in csscope so it won't still fetch CSS from registry
  • upgrade rescope and csscope

v3.0.2

  • add a dummy transform function for (re)transform DOM
  • support re-translate for i18n transformation
  • expose changeLanguage in block.i18n for interface abstraction

v3.0.1

  • fix bug: script in inline bundle doesn't run, because the passed object may be function.
    • fix by running it if it's a function.
  • support rescope.dual-context for multi-phase lib loading bug fixing

v3.0.0

  • rename block.js to index.js - remove block.js and block.min.js

v2.1.2

  • upgrade proxise for nodejs support

v2.1.1

  • fix typo "console.log warn" to "console.warn"
  • minimize js file further with -c -m option
  • trim block code in case of unwanted text children
  • support constructing block.class based on DOM Node
  • support DOM Node as constructor parameter
  • use base64-ed id as scope name
  • only scope CSS if @style is available
  • support nodejs context
  • remove ldquery dependency
  • main as default version since latest / main(version in use) are different concept
  • support rescope v3 and v4
  • remove ldquery dependency

v2.1.0

  • dont use t-attr for attribute i18n since it only works for single attribute. use t-xxx instead.
  • use textContent for i18n if attribute value for t is not available.
  • support recursive i18n transformation

v2.0.7

  • while giving warning, still try to make multi-root DOM works.
  • give warning when block DOM root is a non-element.

v2.0.6

  • remove dompurify dependency.
  • adopt new csscope spec

v2.0.5

  • fix bug: block overwritten by local variable in registry

v2.0.4

  • fix bug: passing function to block.manager's registry doesn't work.

v2.0.3

  • defer block.class initialization until create since we may not use an added block eventually.

v2.0.2

  • add before parameter in attach for insertBefore style attachment.
  • remove useless index.css since users can design their own style
  • fix bug: peer dependencies version incorrect

v2.0.1

  • fix bug: setting registry uses incorrect parameter for updating _reg
  • warn when block.class is constructed without manager.

v2.0.0

  • simplify config by replacing registry with registry.block and moduleRegistry with registry.lib.
    • if only registry.lib is provided, it will be used also for registry.block.
  • support type in registry by passing type as block when requesting block modules.
  • accept additional param type in registry function for distinguishing js, css, block and others.
  • rename setRegistry to registry.
  • rename internal variable reg to _reg.
  • rename set-fallback to chain
  • rename internal variable fallback to _chain.

v1.7.4

  • fix bug: skip undefined when translating

v1.7.3

  • fix bug: csscope in block.manager should be csscope.manager

v1.7.2

  • fix dependency loading: detect resource type automatically before resource loading.

v1.7.1

  • fix csscope upgrade mistake in package.json

v1.7.0

  • support module style( {name,version,path} ) style url
  • support customizing registry in rescope and csscope
  • rename block.class's csscope to csscopes to better distinguish it from block.managers csscope.

v1.6.1

  • fix rescope upgrade mistake in package.json

v1.6.0

  • upgrade rescope to 2.0.1

v1.5.3

  • add i18n.addResourceBundles in block.instance for dynamically adding i18n resources.

v1.5.2

  • show block name/version/path when init fail

v1.5.1

  • bug fix: add missing e in exception handler in manager get function
  • bug fix: in manager, ensure object exist before storing cache data in it

v1.5.0

  • add concept of path in block definition
  • add concept of fallback and fetch in block.mananger
  • use name and version from constructing instead of from module pkg metadata, so the name/version/path data is consistnent and we don't have to define

v1.4.9

  • fix bug: rid.hash is not defined before using.
  • fix bug: global CSS rules from base class are not applied

v1.4.8

  • fix bug: should by-pass scope which style is not extended

v1.4.7

  • remove useless extend option in block.class constructor.
  • add style in extend similar to dom but applied on style.
  • fix bug: block.class.init should also wait for extended class initialization (recursively)

v1.4.6

  • add id for block.class in replace of manual composition of name and version.
  • tweak code flow and remove unnecessary check.
  • add overwrite value in {pkg: {extend: {dom}}} for replacing current false behavior.
  • add DOM transformer for i18n. transformer design is tentative and will probably be changed in the future.

v1.4.5

  • fix bug: block should be scoped in base block's scope too.

v1.4.4

  • add i18n support

v1.4.3

  • fix bug: incorrect parent parameter in init function.

v1.4.2

  • upgrade rescope version to solve scoped / global conflict issue.

v1.4.1

  • add block.init for initialization ( such as rescope.init ) when needed, and init block in block.class since block.class can be used independently to block.manager.

v1.4.0

  • support headless block.
  • support dom overwrite mode ( don't extend dom ) in block extension.
  • fix bug: interface default {} if not provided.
  • add simple headless block and test case.

v1.3.0

  • support global css library
  • upgrade modules

v1.2.1

  • proxisify block.class get to prevent multiple get and multiple scope id for the same block.

v1.2.0

  • support css library
  • fix bug: create block class with data will fail.

v1.1.1

  • get context based on _ctx instead of lib urls so base class context can propagate.

v1.1.0

  • make child block alters and inherits base block's dependencies.

v1.0.0

  • use lderror instead of ldError
  • upgrade modules

v0.0.11

  • access optional data in instance create and attach method. data is also passed to factory methods.

v0.0.10

  • interface is now get from descendant instead of ancestor, to prevent confusion.

v0.0.9

  • upgrade proxise and template for bug fixing and vulnerabilites resolving

v0.0.8

  • return promise in pubsub fire function.
  • return promise in block.instance run function.
  • separate init from the constructor of factory.

v0.0.7

  • support function defined block script.
  • support both function and object as the interface member of block script.

v0.0.6

  • make extend work when defined in pkg field.

v0.0.5

  • update peerDependency version of proxise

v0.0.4

  • remove postinstall since it's for development.