Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Cleancodefactory/BindKraft
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.18.0
Choose a base ref
...
head repository: Cleancodefactory/BindKraft
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Jun 27, 2019

  1. Merge pull request #1 from Cleancodefactory/master

    Merge from Master
    MishoMihaylov authored Jun 27, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    33ec48e View commit details

Commits on Jul 12, 2019

  1. Copy the full SHA
    3c1a4d9 View commit details
  2. Copy the full SHA
    ce7dfdf View commit details
  3. Updated a few docs (IAppDataApi, IAppDataApiContentReader) and added …

    …a get/set property in TemplateSwitcher for requireData
    michaelelfial committed Jul 12, 2019
    Copy the full SHA
    c8e1ba3 View commit details

Commits on Jul 13, 2019

  1. Copy the full SHA
    e62bd0a View commit details

Commits on Jul 14, 2019

  1. Support of Operation and ChunkedOperation as return results from loca…

    …l proxies, some additions to DOMUtil...
    michaelelfial committed Jul 14, 2019
    Copy the full SHA
    de924c2 View commit details

Commits on Jul 15, 2019

  1. Added DelegateRev to order the sealed params like function.bind, star…

    …ted testing the EventDispatcher proxying (bugs still there)
    michaelelfial committed Jul 15, 2019
    Copy the full SHA
    979eb55 View commit details
  2. Fix syntactic error

    rtanev committed Jul 15, 2019
    Copy the full SHA
    d17ee98 View commit details
  3. Fix syntactic errors

    rtanev committed Jul 15, 2019
    Copy the full SHA
    9ab7bc4 View commit details

Commits on Jul 16, 2019

  1. Syntax errors fix

    rtanev committed Jul 16, 2019
    Copy the full SHA
    8f8b515 View commit details
  2. Added a translator for the EventDispatcher (set/get_translator) - has…

    … to be delegate or anything supporting IInvokeWithArgsArray (for speed reasons). Local Proxies now set translators to the proxy dispatchers and the translator translates the arguments if invoke happens.
    michaelelfial committed Jul 16, 2019
    Copy the full SHA
    bfef09a View commit details

Commits on Jul 17, 2019

  1. Add ResizableBehavior to PopDialog and correct names of files

    Nikolay Daskalov committed Jul 17, 2019
    Copy the full SHA
    cbb2d1a View commit details
  2. Copy the full SHA
    e37b165 View commit details
  3. fromDOMElementOffset now returns empty Rect instead of null when the …

    …element's size/pos cannot be determined because it is actually invisible (no offsetParent). And a very important comment in BrowserHistoryTracker!
    michaelelfial committed Jul 17, 2019
    Copy the full SHA
    2c2719d View commit details
  4. text target operation sets textContent with null or something - never…

    … with undefined (Edge problem)
    michaelelfial committed Jul 17, 2019
    Copy the full SHA
    12ea751 View commit details
  5. ...

    michaelelfial committed Jul 17, 2019
    Copy the full SHA
    d0685b0 View commit details
  6. Copy the full SHA
    e843a28 View commit details
  7. Copy the full SHA
    15f220f View commit details
  8. Create CONTRIBUTING.md

    michaelelfial authored Jul 17, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    87f0a2b View commit details

Commits on Jul 18, 2019

  1. UploadBase update

    mishocleancode committed Jul 18, 2019
    Copy the full SHA
    1e0f018 View commit details
  2. Merge pull request #18 from MishoMihaylov/master

    UploadBase update
    michaelelfial authored Jul 18, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    492f387 View commit details
  3. Copy the full SHA
    0c95e7c View commit details
  4. Copy the full SHA
    71b9378 View commit details

Commits on Jul 19, 2019

  1. Add functionality to Set or Reset style flags of window (ex. Draggabl…

    …e and Sizable)
    Nikolay Daskalov committed Jul 19, 2019
    Copy the full SHA
    cec3e80 View commit details
  2. Deleted (not in use)

    rtanev authored Jul 19, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c8e2581 View commit details
  3. AppIndicator and related work, update to Operation.then to migrate to…

    … SugaryDispatcher if an attempt to attach a second callback is made by second call to then on the same operation.
    michaelelfial committed Jul 19, 2019
    Copy the full SHA
    b9c67a0 View commit details

Commits on Jul 22, 2019

  1. Fixed pushHistoryState

    michaelelfial committed Jul 22, 2019
    Copy the full SHA
    ac553c2 View commit details
  2. Copy the full SHA
    5c6cd44 View commit details
  3. Copy the full SHA
    6997cc1 View commit details
  4. Fix whencomplete in Operation to tell clients even if called too late;

    Add Equals Predicates.js;
    AppIndicatorSlot2 has been created and mostly tested;
    Fix in AppGate;
    Added globals Materialize for materialization routines (prev in ViewBase) and added cloneTemplate()
    IShellApi created, implemented by SysShell and registered as LocalAPI;
    Add ILocalProxyCollection and implementation LocalProxyCollection as a way to return multiple BaseObjects (still they have to support IManagedInterface) from a locally proxied method;
    Fixes in appGate and DOMUtilFragment.
    michaelelfial committed Jul 22, 2019
    Copy the full SHA
    303ddf4 View commit details
  5. Copy the full SHA
    91af99f View commit details

Commits on Jul 23, 2019

  1. Update history

    michaelelfial authored Jul 23, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    25defef View commit details
  2. Copy the full SHA
    7532a53 View commit details
  3. Copy the full SHA
    2e42d98 View commit details

Commits on Jul 25, 2019

  1. Copy the full SHA
    c6fed0f View commit details

Commits on Aug 2, 2019

  1. Copy the full SHA
    c587669 View commit details
  2. Copy the full SHA
    ee350b0 View commit details

Commits on Aug 5, 2019

  1. BkInit.KeylaunchMenu - removed the appname parameter (was unneeded - …

    …this is not a critical feature so any inconsistency since last release is not that much of a problem).
    michaelelfial committed Aug 5, 2019
    Copy the full SHA
    321d0cd View commit details
  2. DummyInterfaceProxyBuilder.isProxy - corrected variable name (some mi…

    …xup occurred with this, I hope it is corrected everywhere)
    michaelelfial committed Aug 5, 2019
    Copy the full SHA
    c0d0cc8 View commit details
  3. ...

    michaelelfial committed Aug 5, 2019
    Copy the full SHA
    f639aca View commit details

Commits on Aug 6, 2019

  1. Moved data-viewer template into BindKraft's templates. Fixed a bug in…

    … Class.supportedInterfaces.
    michaelelfial committed Aug 6, 2019
    Copy the full SHA
    827eff3 View commit details

Commits on Aug 7, 2019

  1. some docs

    michaelelfial committed Aug 7, 2019
    Copy the full SHA
    43c3d31 View commit details
  2. docs updates

    michaelelfial committed Aug 7, 2019
    Copy the full SHA
    b74fd49 View commit details
  3. Added optional "item interface" argument to the LocalProxyCollection'…

    …s constructor. item(x) will cast to that interface if specified (through creating a proxy the other side will use as a template).
    
    Corrected returned Operations by the proxy (errors were reported as a success).
    michaelelfial committed Aug 7, 2019
    Copy the full SHA
    75b2286 View commit details

Commits on Aug 8, 2019

  1. updates

    michaelelfial committed Aug 8, 2019
    Copy the full SHA
    595c8e5 View commit details
  2. fix extendinterfaces

    michaelelfial committed Aug 8, 2019
    Copy the full SHA
    fac39ee View commit details

Commits on Aug 13, 2019

  1. Revert the ChunkedOperation.chunk's behavior to what we have in maste…

    …r (a change was experimented in develop) - first callback catches success, the second - failures. Added anychunk with a single callback that receives both success/failure. Success an failure are too arbitrary and this seems better behavior. Added onsucces, onfailure and others in Operation.
    michaelelfial committed Aug 13, 2019
    Copy the full SHA
    7c00355 View commit details
  2. Copy the full SHA
    d0e89f2 View commit details

Commits on Aug 16, 2019

  1. Add infofs:/appinfo/<AppClass> directory with tooling and local API s…

    …imilar to those for AppData (in BkInint and in IAppInfoApi)
    michaelelfial committed Aug 16, 2019
    Copy the full SHA
    fc41920 View commit details
  2. ...

    michaelelfial committed Aug 16, 2019
    Copy the full SHA
    1e2bc1a View commit details
Showing 953 changed files with 41,780 additions and 34,594 deletions.
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"cSpell.words": [
"issealed",
"sealcheck",
"userselection"
]
}
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Contribution

Currently any external contribution will require explicit arrangements. More streamlined rules will be put here when this becomes possible.

The reason for this temporary mode is the fact that BindKraftJS is a core with potentially number of modules that can extend it - differently in different projects. Also the integration with the server is a matter that makes running it a bit difficult without deeper knowledge of the platform. The forthcoming features and example platform setups will solve these problems and enable anybody to familiarize with the basics even without additional help - and that is the moment when the contribution will take more typical shape.

__When to expect that?__

I cannot define exact time frame, but I hope that before the end of 2019 there will be enough introductory materials to make it possible for everybody to use BK over various servers and as a consequence form opinions, ideas for features, components and so on - everything needed in order to make the source code contribution possible without the need to be led personally though obscured plans, abstractions and principles.
1 change: 0 additions & 1 deletion Configuration.json
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
"InterfaceAsString": "Ccf.Ck.SysPlugins.Interfaces.IDataIteratorPlugin, Ccf.Ck.SysPlugins.Interfaces",
"Default": true,
"CustomSettings": {
"MyCustomsetting": "Iterator"
}
},
"NodesDataLoader": [
10 changes: 7 additions & 3 deletions Dependency.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
{
"name": "BindKraft",
"version": "1.0.0",
"description": "",
"version": "2.23.8",
"description": "Large browser Javascript library. Provides templates, class inheritance and interface implementation, runs OS-like workspace with multiple apps and windows.",
"keywords": [],
"author": "Clean Code Factory",
"license": "MIT License",
"dependencies": {},
"signals": [],
"release": [
{
"version": "1.0.0",
"version": "2.19.1",
"info": "Initial creation"
},
{
"version": "2.23.8",
"info": "2021 Feb head"
}
]
}
23 changes: 19 additions & 4 deletions Documentation/Advanced/ManagedProxies.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
<!-- vscode-markdown-toc -->

* 1. [Requirements](#requirements)
* 2. [How this works and where is it used](#how-this-works-and-where-is-it-used)
* 3. [Proxy generation](#proxy-generation)
* 3.1. [What are the strict and non-strict modes?](#what-are-the-strict-and-non-strict-modes?)

<!-- vscode-markdown-toc-config
numbering=true
autoSave=true
/vscode-markdown-toc-config -->
<!-- /vscode-markdown-toc -->

# Managed proxies

(This is advanced topic. Typically one only needs to know that these proxies exist).

The so called `managed proxies` are intended to provide isolation between client and server locally (inside the local workspace).

Despite the similarities between remote and local stubbing techniques they have very different natural limitations. This is the reason for the existence of two different and somewhat similar sets of interfaces and classes in this area.

So, the local proxies can be seen as collapsed remoting and as proxy and stub combined into one and the same object. For the developer there is a more important difference - the local isolation (through the proxies) does not require all methods to return operations (to be asynchronous). This alone justifies the existence of the local proxies.

## Requirements
## 1. <a name='requirements'></a>Requirements

A local (managed) proxy can wrap only interfaces extending the `IManagedInterface`:

@@ -22,7 +37,7 @@ The implementation of the interface is actually very simple, because:

>The `GetInterface` method have to be implemented, but this is done in a very trivial manner. The server class have to implement it as simple method returning the reference to the object on which the requested (in the `iface` argument) interface is implemented. The rest of the work is again done by the internally generated proxy.

## How this works and where is it used
## 2. <a name='how-this-works-and-where-is-it-used'></a>How this works and where is it used

These client-server relations can potentially exist in quite many scenarios - anywhere where isolation between client and server code is preferred/required. I.e. in general all the Javascript in the local workspace runs in the one and the same Javascript workspace context - the javascript context of the WEB page. At a very general level any two objects in the workspace may have some way one of them (the client) to request a reference to the other (the server) based on some interface known for the both parties (implemented by the server, called by the client). We ignore for the moment how and what enables the client to find the server and request the interface, but this mechanism is the one that decides to pass a direct reference or a wrapped one that will not allow the client to call on the server any methods that are not part of the requested interface, thus establishing certain level of isolation between them.

@@ -34,7 +49,7 @@ In BindKraftJS such relations are maintained through two mechanisms (in version

It is not prohibited to implement custom scenarios like these. So, the technique and the involved mechanisms are open for wider use if somebody deems them useful and appropriate in a custom scenario.

## Proxy generation
## 3. <a name='proxy-generation'></a>Proxy generation

It is probably already obvious that the bulk of the proxy generation work will be done by the system behind the scenes, but there are cases in which the developers have to wrap references to objects themselves. Another reason to familiarize with the proxy generation is to know how, why and when to control/configure it.

@@ -62,7 +77,7 @@ Here the `strict` argument is optional and if omitted the new instance will just

There are further considerations for the strict and non-strict mode and it is highly recommended to use non-strict mode only for development time testing and experimenting. It is also important to notice that this is better done through BindKraft core settings and not through `new DummyInterfaceProxyBuilder(strict)`. The reason is that the builder generates a new class for each proxy and the strict/non-strict mode argument will have effect only when the builder generates a proxy for that interface and server class for the first time. Just have this in mind and do not use non-strict mode in production!

### What are the strict and non-strict modes?
### 3.1. <a name='what-are-the-strict-and-non-strict-modes?'></a>What are the strict and non-strict modes?

In strict mode all the requirements are either enforced or cause exceptions if they are not met. In non-strict mode one can cut some corners. This is sometimes done by the system, but is not recommended otherwise.

23 changes: 23 additions & 0 deletions Documentation/Ajax/AjaxArchitecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# BindKraft Ajax architecture.

This architecture was and is developed after version 2.24. It obsoletes the old jquery based one.

## Architecture brief

A complete construction capable of handling ajax requests is called henceforth a `pipeline`. One or more `pipelines` can exist in memory, but only one is the system default pipeline. It is not encouraged to use private pipeline instances, but in some rare cases this could still be desirable and is perfectly possible.

Each pipeline has the same general construction:

1. **Request sender utility.**

Usually implemented as `implementer` this becomes part of the classes that use the pipeline.

The sender utility schedules the request into the ajax queue (`IAjaxSendQueue`) as an object implementing `IAjaxRequest` interface.

2. `Queue inspectors`

A set of `IAjaxSendQueueInspector` objects is configured to monitor the queue.

The inspectors implement filtering of the requests by various criteria and most often by using `IRequestInspector` objects.

Each queue inspector serves one carrier TODO....
52 changes: 52 additions & 0 deletions Documentation/Ajax/configure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Configure pipeline

There are BKInit classes for use in `init.js` files, that configure pipeline(s). Most often only the main pipeline is configured, but it is possible to configure custom ones for use only in specific app(s).

## Configuring main pipeline

This is an example and incomplete configuration, we use the argument names from it further in the document:

```Javascript

BkInit.AjaxPipeline(function(pipeline){
pipeline
.useDefaultSendQueue()
.useProgressQueue()
.AddCarrier(function(carrier) {
carrier
.name("server.com")
.addPickRule(function(picker) {
picker
.criticalLimit(10)
.criticalAge(1000)
.pickLimit(5)
.rule("AjaxRequestInspectorUrl", function(inspector) {
inspector.set_server("*server.com");
});
})
.poolSender(2);
})
.AddCarrier(function(carrier){
carrier
.name("canceller")
.addPickRule(function(picker) {
picker
.criticalLimit(10)
.criticalAge(1000)
.pickLimit(5)
.rule("AjaxRequestInspectorUrl", function(inspector) {
inspector.set_server("*");
});
})
.cancelRequest();
})

});

```

### pipeline settings

`.useDefaultSendQueue()` - Uses the main send queue. It is recommended to use it in the main pipeline only. See below how to create additional queues when creating custom pipelines.

_Note that it is possible to have multiple pipelines using hte same send queue, but such a scenario is very hard to configure in any predicable fashion and it is not recommended._
100 changes: 100 additions & 0 deletions Documentation/BKInit_urlCommands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# BKInit.urlCommands

Contents
- Methods
- IUpdateCommandUrl service
- urlcommands command ( alias: runurlcommands2)
- Security considerations

Basic syntax, example:

```Javascript

BKinit.urlCommands(function(ucmds){
ucmds.setRunName("run");
ucmds.addRunScript("alpha", ["id", "x"], '... script source ...');
ucmds.clearAllScripts();
});

```

## Methods

### setRunName(name)

Defines the name of the query parameter that lists the scripts to run on startup.

The parameter must contain a list of registered (with addRunScript) scripts delimited with a comma without any spaces. For URL generation see `IUpdateCommandUrl` service.

the default name is "run". Workspace constructs should not depend on the defaults - any module they use can potentially change it - it is recommended to override the name in the top module even when its modules are supposed to register url commands on their own.

### clearAllScripts()

Removes all script registrations. Useful when overriding any configured scripts in a module.

### addRunScript(name, constants, script)

Registers a script for the feature. Only registered scripts can be executed when listed in the run query string parameter (see setRunName).

**name** - The name of the registration and the script

**constants** - Array of parameter names - constants stripped from URL query string parameters.

**script** - String, the script source code.


## IUpdateCommandUrl service

Obtained from LocalAPI e.g.

```Javascript

var api = new LocalAPIClient();
var ucmd = api.getAPI("IUpdateCommandUrl");
if (ucmd.isRegistered("mycmd")) {
var url = BKUrl.startURL();
url = ucmd.updateUrl(url, "mycommand", {id: 5, x:"some value"});
if (ucmd.isRegistered("mysecondcmd")) {
url = ucmd.updateUrl(url, "mysecondcmd", {a: 1, b: "value b", c: 123.34 });
}
// Do something with the url
}

```

The above code will generate something along the lines (assuming corresponding configuration exists):

```
http://server/?run=mycmd,mysecondcmd&mycmd.id=5&mycmd.x=some%20value&mysecondcmd.a=1&mysecondcmd.b=value%20b&mysecondcmd.c=123.34
```

URL containing commands are generated for various reasons, but they usually share the aim to allow somebody to cause certain effects when the workspace is opened with the URL clicked/placed in address bar etc.

Such URL are often sent through e-mail or other messages to give an user URL that will cause the workspace to do something while starting up. For example this can be a new user of an application, provide user with initial state/scenario in some app etc.

**What is the difference between app treestate (routing) and url commands?**

- The tree state when reflected in the URL causes an app to navigate internally to a given state (if available). That state is persistent - unless removed by some means one can go to this state again and again.
- URL commands execute script code. Of course the script can do something similar to routing if it is written that way, but it is an action and as such it can perform actions on behalf of the user entering the system with that URL and most often they would be one-time operations or other tasks that can be compared with actions performed by the user with the UI.

**Example scenario in a couple of sentences**

Let us imagine some app (no matter what exactly it does) that defines some resource shared by several users. Users are invited to join and this is done using URL commands.

1. The app offers UI where invitation is created and sent
- Some data is saved (typically in database) to identify the invitation as entity
- The invitation id is used as constant to create an URL running a command with that id constant on startup (using `IUpdateCommandUrl` API). The resulting URL is sent to the the invitee by email or other means.
- That command has to be implemented to start the app and ask it to check and execute the invitation - load it by the id constant, check if the logged user has the same email for example and if everything is Ok register the user with the resource.
2. The invitee opens the URL and the command is executed with the encoded constants in the URL.

Of course, we skip the authorization here, but such invites usually happen in two possible ways - for already authenticated users and for users who need to authenticate or even create account before entering the workspace. This means that the authorization process have to preserve the query parameters during the authorization or registration and include them in the final redirection URL. The CoreKraft authorization does that and in general this is usually just a matter of preserving a fully composed redirect URL during the process.

## urlcommands command ( alias: runurlcommands2)

The `urlcommands` is a built-in BindKraft command that must be included in the boot script to invoke the execution of the url commands encoded in the URL with which the workspace is opened. Choosing when to invoke the command will depend on specifics of the project. For example a project may need an app or apps to run as daemons all the time and the task that needs to be performed by some of the commands is expected to need their services. In such a case - `urlcommands` should be invoked after starting the daemons. This kind of argument clears the decision - the workspace has to be functional enough before running the command. The initial URL is preserved and can be used at any time, so the only consideration is to make sure the commands and whatever they invoke indirectly will have the services needed at hand.

## Security considerations

Normally it should not be necessary to even talk about security in this context, but feature like this can potentially tempt an inexperienced developer to implement url command that performs unsafe operations. Still, whatever the problem in actuality it cannot be caused by the urlcommands feature itself - if there is a security problem it would be caused by availability on the client side of a code that can do harm - if it exists it is a matter of finding a way to exploit it, hence urlcommands just execute other code and security concerns are about the code not its specific execution in this case.

So, urlcommands do not pose additional security concerns by themselves, but they can surface an existing problem.
3 changes: 3 additions & 0 deletions Documentation/BKProject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# BKProject

TO DO
File renamed without changes.
18 changes: 9 additions & 9 deletions Documentation/BindKraft.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# BindKraftJS (for krafty programmers) - architecture
# BindKraftJS (for krafty programmers)

This document is the starting point of the whole BindKraftJS documentation and describes the construction of the BindKraftJS
This document is a good starting point of the whole BindKraftJS documentation and describes the concept of the BindKraftJS

## Workspace

BindKraft considers a WEB page as a **workspace**. Colloquially this is often called (even in this documentation) - a _desktop_ or a _system_ and this is not by accident. Unlike most WEB oriented programming frameworks/environments, BindKraft is making the jump that the powerful WEB browsers of our time made possible - to not consider a WEB site (location) as a just page anymore, but as a place for work - a work place where the user can perform a number of complex tasks with tools available at this place.
BindKraft considers a WEB page as a **workspace**. Colloquially this is often called (even in this documentation) - a _desktop_ or a _system_ and this is not by accident. Unlike most WEB oriented programming frameworks/environments, BindKraft is making the jump that the powerful WEB browsers of our time made possible - to not consider a WEB site (location) as a just page or SPA (single page application) anymore, but as a place for work - a workspace where the user can perform a number of complex tasks with tools available at hand.

So, the site/page is a **workspace** filled with tools we call **apps** (or often applications) that the visitor may start and stop many times, feed them with different data, open with them different items, mix the products of these apps in any of the ways they allow and so on. All this is supposed to happen on a single WEB page, living in the visitor's browser.

This point of view is very similar to the way one sees the workspace provided by the OS running on your personal computer, phone, tablet or other individual device of a similar kind.
This point of view is very similar to the way one sees the graphical workspace provided by the OS running on your personal computer, phone, tablet or other individual device of a similar kind.

>If we consider this in comparison to the classic way we've seen the WEB for many years, it will look like BindKraft sees the user NOT as someone who uses the WEB browser to look at series of pages, but RATHER as someone who browses through various **workspaces** (desktops), each tailored for certain kinds of activities, pre-configured with access to relevant data and services.
The page-centric approach remained intact despite the huge advances in the WEB browser capabilities during the last decades and in one way or another limited the functionality of almost all the WEB development frameworks and tools, no matter how much of the work they moved to the browser. The very concept was the most limiting factor. It kept the separate functionalities living in separated pages with limited ways to cooperate, because of this same separation and no matter how much tasks became possible in the WEB browser (instead of requiring native desktop implementation) they remained a bit out of place in a world still following the basic concept the WEB followed in its first years - page browsing environment.
The page-centric approach remained intact despite the huge advances in the WEB browser capabilities during the last decades and in one way or another limited the functionality of almost all the WEB development frameworks, no matter how much of the work they moved from the server to the browser. The very concept was the most limiting factor. It kept the separate functionalities living in separated pages with limited ways to cooperate or has gone to the other extreme - treated pieces of functionality that should be separate apps as components of a single bloated application.

We simply recognized the fact that even as early as (let say) 2010 the browsers were already way beyond just page viewing contraptions, they were ready even then to offer the programmer a highly portable, zero-maintenance, installation-free desktop replacement for many kinds of work. The further development of the WEB browsers only makes this statement true for more and more tasks usually associated with the desktop workspace.

@@ -22,13 +22,13 @@ With BindKraft we call each WEB page - a workspace. BindKraft boots the workspac

While BindKraftJS is immeasurably simpler than an OS (operating system) it shares a common concept:

A system of functionalities has to be prepared during the boot process
A system of local services has to be prepared during the boot process, some apps started as daemons or as front UI.

Then this system forms a workspace UI environment where the user can use it.
Then this system forms a workspace UI environment where the user can do some work.

Therefore, what traditionally is seen as page is a context in which BK initializes that system of functionalities. They are prepared to be provided to all the apps that will work there as various services and API and then the UI part is started to enable the user to control the apps and work with them.
What traditionally is seen as page is a context in which BK initializes that system of services. They are prepared to be provided to all the apps that will work there as various services and API and then the UI part is started to enable the user to control the apps and work with them. In a fashion similar to an operating system the UI can be a controlled by a shell app that lets the user to start apps and switch between them or the UI can follow the opposite approach - still use many apps, but present them in an integrated way that resembles a WEB site. Depending on the design approach these facts can be obvious to the end users - e.g. UI betting on draggable windows and task bar will be expected to act as a desktop environment, but UI with all the windows maximized with a few dialog boxes will exploit the user expectations based on experience with more typical WEB pages. Still, the functionality behind all this is the same and the design philosophy is a matter of choice made by the developers.

## The architecture

BindKraftJS is built in Javascript entirely.
BindKraftJS is built in Javascript entirely. It is using two techniques internally - both opposite to one another. The UI parts are normally built with HTML templates bound to code controlling them in a template-first fashion, the non-UI parts use the opposite - code-first approach, where classes are written to form apps.

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Documentation/BindingSyntax/DataClass.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Class attributes

TODO: write this
3 changes: 3 additions & 0 deletions Documentation/BindingSyntax/Markers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Markers - marker attributes

TODO: Write this article
36 changes: 36 additions & 0 deletions Documentation/BindingSyntax/options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Options

Options in the binding syntax enable or disable certain features and behaviors. The reasons to need an option to do so will vary - from mutually exclusive behaviors to potentially damaging ones (if not used where appropriate), to performance related.

## Syntax:

`options=option1,option2,option3,...,optionN`

The options are listed as keywords (see the list below), separated by commas, without any spaces between the keywords and the commas or the "=" sign.

example:
```
options=async,freezesite,operation
```

## Supported options:

`disabled` - disables the binding's `updateTarget`/`updateSource` functionality. Direct usage of the `set_targetValue`/`set_targetValue` will continue to work - i.e. direct usage of the binding is not disabled, but its participation in mass updates is.

`async`, `asyncread`, `asyncwrite` - asynchronous processing of the updateTargets/Sources. The `async` will perform both asynchronously, while `asyncread` is only for `updateTargets` and `asyncwrite` only for `updateSources`. Internally this is done with this.async (see `BaseObject`) which creates a task and registers it with the global task scheduler for execution (_For beginners_: _this is advanced technique that "replaces" the setTimeout._). Using asyncwrite or async on read/write bindings (of type [`bind`](bindingtype.md)) is not recommended, because the source updates are typically expected to be synchronous. These work witn `data-on-event` bindings too. In that case they will invoke the handler asynchronously - in a scheduled async task. This can be used when the handler performs heavy processing you want to delay in order to keep the browser responsive.

`freezesite` - If the target supports `IFreezable` will freeze it while setting the target value. This is especially useful when the property being the target of the binding invokes complex processing when set.

`persistable` - enables the binding to change the data entity state when performing update sources. For example if the binding path is `a.b.c` the state of the object at `a.b` will be updated. (TODO: Document the data state API after rearranging it more logically)

`operation` - works only for `updateTarget`/`set_targetValue`. If the binding receives an `Operation` as a value to be set on the target, it will await the Operation and set its result to the target. If the flag is not specified the Operation itself will be assigned. Both behaviors can be desired - you may have an object dealing with an `Operation` (or more than one of them) on its own internally or an object that does not deal with Operations and should receive the result when available.

`nodefault`, `preventdefault` - works only on `data-on-domevent` bindings and only for DOM events. Prevents the default processing (see preventDefault of the DOM event)

`nopropagation`, `stoppropagation` - (new from version 2.21), works only on `data-on-domevent` bindings and only for DOM events. Stops te DOM event propagation. All handlers on the current element will be called, but the event will not propagate further to other elements.

**Old options**

`nonpersistable` - For backwards compatibility this is still supported. In older versions (much older) the functionality now enabled with the `persistable` option (see below) was "on" by default and the `nonpersistable` option excluded bindings from it. This mode can still be turned on and this option will make sense then. However, this mode is extremely inconvenient and will be fully deprecated soon (even the ability to turn it on).


185 changes: 185 additions & 0 deletions Documentation/BindingSyntax/ref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# ref

Example:

```
{bind source=something path=something ref[name1]=a/b:bindingname ref[name2]=a/b@prop ref[name3]=a/b~dcprop.dcprop2}
```

The `ref` binding parameter exposes a reference to something else in the view or a value extracted from a specified location. Multiple `ref` parameters can be specified in a single binding as long as their names (specified in square brackets) are different.

They can be accessed by any code that has access to the binding:

_Most common_

- in the handler specified in a `data-on` binding. The 3 argument of the handler is the binding and it can call `binding.getRef("refname")` to obtain the reference.
- in custom formatters - again the binding is the 3 argument in their ToTarget/FromTarget (_adHoc formattters_) routines (_Read/Write methods in custom formatters implemented as classes derived from CustomFormatterBase_).

_Less common_

- Binding obtained directly - found through `Base.findBindingByName` for instance.

The `ref` parameter in a binding is mostly useful in `data-on` kind of bindings, but can be also employed in data-bind bindings by a custom formatter used by the binding. This is also accessible for system formatters, but it is unlikely to find an useful case for a system formatter to use a binding reference.

The main purpose of the `ref` parameters in a binding is to provide additional references/values from "places" in the view to the handler (data-on) or formatter/converter (data-bind) needed for their operation. Teh view (template) designer can provide the same references/values even if the view changes by changing the `ref` paths to point to the same object or value.

## Syntax

There are 3 kinds of expressions that can be specified in a `ref` setting. They can address respectively- a binding by name, a BindKraft object attached to a DOM node, data in the data context locally and at the location of arbitrary other DOM element in the view/template.

The syntax has the following forms:

```
for bindings
ref[myref]=<parentkey>[/<childkey>]:<bindingname>
for data-classes and inside them
ref[myref]=<parentkey>[/<childkey>]@
ref[myref]=<parentkey>[/<childkey>]@<someproperty>.<itsproperty>
for data context
ref[myref]=<parentkey>[/<childkey>]~
ref[myref]=<parentkey>[/<childkey>]~<someproperty>
```

### parentkey / childkey part of the address



Here `myref` is the name of the reference which is specified in accordance to what the handler or the custom formatter(s) using the reference expect. It should be specified in their documentation (check their source if there is no other information).

The `parentkey` is the `data-key` of parent (ascendant) DOM element in the template/view or one of the special keywords:

* `self` - denotes the element on which the binding is defined

* `__control` - denotes the closest parent component border - a DOM element with a `data-class` implementing the `IUIControl` interface.

* `__view` - denotes the root element of the current view (should not be used in controls - components that carry and materielize their own templates).

The `childkey` is optional and if used has to be the `data-key` of a child element of the element identified by the `parentlkey`.

The `parentkey` and `childkey` together determine an element. If more then one element can be identified - the first one in DOM tree order will be used. This should be avoided for usage in `ref` and if it happens the `data-key`-s should be changed to provide unique identification of the concerned elements.

### Addressing bindings

```
ref[myref]=<parentkey>[/<childkey>]:<bindingname>
examples:
ref[indicator]=self:colorupdater
ref[units]=formroot/unitspanel:unitsfield
```

From the element determined by the parentkey/childkey part is used as base from which to find a binding that specifies a setting `name` equal to the `bindingname` specified. The search is case sensitive, but as a convention lower cased names are recommended.

> The search for the binding with the specified `bindingname` proceeds as follows: The addressed element (by prentkey/childkey) should, preferably, have a `data-class`, if this is so all the bindings on elements inside that element will be searched, but not the bindings on the element itself.
> If the addressed element has no `data-class`, the search will start from its closest parent that has `data-class`. This option is obviously a potential source for mistakes and not recommended. It is kept available for legacy compatibility reasons.
**On the consuming side**

The ref is most commonly used in event handlers, so we will talk about them, in custom formatters there is no difference except the typical reasons for the usage of references.

Assume this piece of HTML with bindings as part of a template/view

```html
<div data-key="formsegment">
<input type="text" data-bind-val="{bind path=somefield name=count}">
<button data-on-click="{bind source=__view path=onDoSomething ref[amount]=formsegment:count">click me</button>
</div>
```

According to the HTML above the handler is in the view (not important for the example). Assume it does something that determines logically some "amount" value and needs to update it into the UI, but on behalf of the user without updating the data, which is supposed to happen after the user enters some more data in other fields not shown in the example.

```javascript
SomeView.prototype.onDoDomething = fnction(event, dc, bind) {
var x;
// Something is done here and x is set to a number specifying the determined amount.
// now let us autoset it in the UI.
bind.getRef("amount").set_targetValue(x);
}
```

Of course one can find the `input` element and set its value through DOM and even with the help of BindKraft, but using the binding obtained through the ref has multiple benefits. Here are some of the most noticeable of them:

* If the `input` is some day replaced with a different field - a dropdown for example. The binding will bind to different property (if needed), may need different formatters and so on, but if it keeps the name the code will still work without changes.

* Through the binding the formatting/conversion specified in it will happen - by default it will be applied in the respective direction for `get_targetValue` and `set_targetValue`. This still can be turned off when needed for get_targetValue if called like `binding.get_targetValue(true)` - the optional boolean parameter disables the backward formatting when reading from the target if set to `true`.

* One can access more from the binding, for instance not its target, but the source - using `get_sourceValue` and `set_sourceValue` (no formatting by default). Other methods of the [Binding](../ViewClasses/Binding.md) class are also available and enable the handler to use the binding's capabilities when needed.

The most important effect is perhaps the fact that the handler's actions will be indistinguishable from normal binding for the target or the source of the binding.

### Addressing data-class objects and inside them

```
ref[myref]=<parentkey>[/<childkey>]@
ref[myref]=<parentkey>[/<childkey>]@<someproperty>.<itsproperty>
```

With this syntax the addressed element by the parentkey/childkey part has to have a `data-class` or one will get only null from the reference.

When the reference just ends with the `@` symbol, the `getRef("myref")` in code will return reference to the object specified by the `data-class` attribute on the element. For example in a handler you can do something like this:

```javascript
MyView.prototype.onSomething = function(event, dc, bind) {
// update the sources in another part of the templete
bind.getRef("myref").updateSources();
// or update targets - be careful to not overlap areas anyway
bind.getRef("myref").updateTargets();
// Make sure what the class is and call a specific method defined on that class (your own class or BK class - whatever you need)
if (BaseObject.is(bind.getRef("myref").updateTargets(), "SomeClass")) {
var x = bind.getRef("myref").someMethod(/*some arguments*/);
}
}
```

Up to this point we are talking about an usage where you know the class or calling methods/accessing properties in general manner - assuming a common base class ([Base](../ViewClasses/Base.md) for instance), but what if your code needs to be unaware of the class of the addressed object?

In such a case one can specify a property chain after the `@` symbol.

```
ref[myref]=key1/key2@prop1.prop2
```

Property names are separated with "." dots and the reference will return the property value or null if the chain hits a null or undefined somewhere. Depending on what you have in the addressed property you can do more than just read values - if the property contains a reference to an object, you can check its class, call its methods get/set it properties and so on. The only recommendation is to not forget the type checks before performing the actions you intend to do and if you are a good guy throw an informative exception when the type doesn't match your expectations.

The property path will get values from both javscript fields and get_propertyname properties. The get_ properties will be tried first if you have of the both kinds with the same name. Note that the `$` prefix is not supported here and you cannot distinguish between "active" properties implemented as get/set_ methods and normal javascript fields. This may look as inconsistency, but is intentional - prevents reliance on specifics in case the desired path changes even in nature (how the properties are implemented). This reflects the main purpose of the references - to provides means through which the code can be written in a manner resistant to small and moderate changes in the templates/views.

> The main benefit of using this kind of references is to make a code (usually handler methods) resistant to template/view design changes. The designers have to maintain the references and point them to the new locations where the expected objects reside and the code will continue to work without changes.
Again, like in the other references, there other ways to find the objects you need, but none of them is implicitly interwoven with the template design and they will either case mistakes way too often or if your team is careful will, at least, become a stopper for template changes - for both design and functional reasons.

### Addressing data context

```
ref[myref]=<parentkey>[/<childkey>]~
ref[myref]=<parentkey>[/<childkey>]~<someproperty>
```

The `~` symbol after the parentkey/childkey part causes the getRef for that reference to return the data context visible at the addressed element. Using the `self` keyword will address the data context at the binding element, the other special parent keys will address the actual data context at other locations as expected.

The property path behaves exactly the same as in the other case - when addressing data-class objects and if omitted getRef returns the data context, if present - the value of the property addressed by the `prop1.prop2...` chain. For example, presume you need the FirstName property from a data context of another part of your template/view.

```html
<button data-on-click="{bind source=__view path=onSomething ref[firstName]=somecommonparent/somekeyfromtheotherpart~FirstName}">
```

```javascript
MyView.prototype.onSomething = function(event, dc, bind) {
var firstName = bind.getRef("firstName");
// use it for whatever it is needed.
}
```

Handlers of DOM events receive the data context in which resides the element on which the event is intercepted, but this is not true for the custom events fired by BindKraft classes - some might do it others don't - it depends on what they consider relevant data and they can be designed for usage not only in templates, but from code. Long story short - using ref[dc]=self~ one can pass the local data context to the handler even when it is not passed as second argument to the handler.

> Benefits of references pointing data contexts or parts of them is the flexibility of the data context design and separation that is achieved this way. The handlers that use such references can remain unchanged if the data context and its distribution in the view changes by updating the references in the bindings that activate them.
> Sometimes a handler has to consider several values from different data contexts in order to do its job and the only way to achieve a good solution to such a problem without references will be to stick to a strict MVC pattern, which has downsides of its own - the most prominent of which is the need to black box too many pieces of your templates which effectively defeats the purpose of using templates when this goes too far.
## Remarks

The binding references are a simple and powerful technique to solve problems that cna otherwise force the programmer to structure the code and the templates in inconvenient ways that will also often double and triple the code need to cope with them. However, like everything else, the binding references can be used wrongly and become a source of problems on their own. If you are using references everywhere and many of them - you are probably overdoing it.

This feature is designed to help the programmer keep code and templates in balance and one can break this balance in both directions- by avoiding references and by using them when something should go into the code. The majority of the modern frameworks and UI programming environments avoid similar features (as appropriate for their respective UI mechanics) in an attempt to force the programmers to stick to some strict patterns (most often MVC and derived), but if you look at it more sanely, they always lead to extensive black boxing - i.e. templates become smaller and smaller, single forms/views can no longer be designed as a single template or even as reasonably nested granulated templates. It is a common sight to see frameworks initially loved for their template features become a mess where one needs dozens and even hundreds of "couple of lines" templates in order to design the thing. BindKraft recognizes the effect and references are one of the features that helps the developer to keep control over the granulation. The real world projects are not and cannot be designed as perfect black boxed components (we call those controls), the boxing is not a straightforward process applicable everywhere - components have to vary in their specialization and context bindings in order to keep projects consistent - e.g. it is obvious that you can completely black box a color picker component, but this is not wise for a component specific for a project, where black boxing will force the programmers to feed it a serious amount of data that it can actually get itself easily without much abstract techniques if it is acceptable to access from it stuff that you know is always present in the project. Abstract techniques (services, DI etc.) are a good thing, but when you have to solve concrete problems they just turn into trouble planned in haste further granulating your code, thus making any mistake even harder to fix. Using references and other BK techniques one can moderate the complexity, but nothing comes as a gift - you have to avoid overdoing it in either direction.

57 changes: 55 additions & 2 deletions Documentation/BindingSyntax/source_service.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,60 @@
# binding source/service attribute
# binding source/service/translation attribute

`Source` is mutually exclusive with `service` and the reason is quite obvious - they both specify the same thing - the source of the data binding. The `source` supports syntax to do that mostly in the same view and a few special places, while te `service` is responsible for entirely different direction - on based on local service location mechanisms.
Optional attribute specifying the source of the data binding. It works together with the `path` attribute - the source points at the start point (object), `path` defines the path from there. Source, service and translation are mutually exclusive.

Currently 4 types of sources exist:

## None (no source, service or translation is specified.)

The binding's source is the data context applicable to the element on which the binding is specified.

**Important!** A frequent mistake that may occur is to consider the parent data context while actually writing a binding on an element with separate data context. If the parent context is needed use `source=parentcontext`.

## source

In general this attribute specifies the starting object by using the `parent/child` data-key navigation.

Example:

```HTML
<div data-key="area1">
<div data-key="area2">
<input type="text" data-bind-val="{read source=area1/input2 path=$value readdata=$valchangedevent}"/>
</div>
<div data-key="area3">
<input data-key="input2" type="text"
data-class="TextBox"
/>
</div>
</div>
```

In this example the only binding refers to the second text box and loads its value into the first one when it changes.

**This attribute also defines a number of special targets:**

* `self` - The element or if there is a data-class specified on it - the instance of that class attached to the element.

* `static` - Static value useful for some parameterizations or for tests. A `text`, `number` or `object` directives can be used to specify the value. The text and number need value in quotes e.g. `number='8'` and object specifies a class name or the keyword `object`. e.g. `object=object` will assign empty simple javascript object which is often convenient for local data contexts filled with bindings. Example: `{read source=static text='some text'}`.

* `globalresource` - deprecated.

* `appletstorage` - obsolete, will be deprecated.

* `systemsettings` - provides access to the system settings. Programmatically available under the `CSystem.Default().settings` as plain JS object tree.

* `settings` - Reserved for future use.

* `parentcontext` - Will work like a binding without source, but will always look in the data context outside this element. This is often needed in components that change their data context, but need some of their properties to be bound to data in the outer data context.

* `__view` - Works in views only (inherited from ViewBase), refres to the root element of the view. Can be used with a child key e.g. `source=__view/input2` will find some (presumably) input element named input2 in the view.

* `__control` - Works inside components implementing `IUIControl` interface. This is a marker interface which isolates to some extent the component from the rest of the template in which it is placed. Refers to the root element of the component (it does not matter how it was materialized - from template or in-place). For more information see `components`.

## service

Uses the service location features to find the first exposed service of the specified type.




147 changes: 147 additions & 0 deletions Documentation/BindingSyntax/targetops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Supported target operations in bindings

This document lists all the supported built-in target operations and additionally lists the rules for binding to indexed and non-indexed properties of BK class instances attached to elements of the template with the data-class attribute (in the end of the document).

## Built-in target operations

**text**

Sets/gets the text content of the element. When set all internal structure is destroyed and replaced with plain text.

**val**

Sets/gets the value of an element. Not all HTML elements have a value property! This will have no effect on those who don't.

**html**

Sets/gets the inner html of an element. No processing is performed on the html text - any BindKraft attributes specified in it will have no effect. Good for setting of small segments of HTML formatted content.

**src**

Sets/gets the src of a HTML element - not all have one and this will have effect only on those that have one (img for instance).

**checked**

Historically some form fields in HTML, the check boxes and radio buttons, have both value and checked property, but we are actually interested more if they are checked or not, while their value is of a little use in the browser. This operation sets/gets as boolean the checked state of these elements - no effect on other HTML elements. Please note that using radio inputs in browser javascript applications is not a good idea, they were designed with a special behavior for form submits and this behavior is nowadays more of a problem, than a blessing. It is better to use SelectableRepeater and images or some other method to show something that looks like radio button instead of the input type="radio" input.

**elementtitle**

Sets/gets the element title - shown by all browsers in a tool tip when the mouse hovers over the element. (Mobile behavior is not yet fully determined by all browsers. devices with pens will show it on hover, like the mouse case, but with capacitive touch-only screens the title is rarely visible)

**elementreadonly**

Sets/gets the read-only state of a HTML element. Will work with form field elements only.

**elementdisabled**

Disables(true)/enables(false) an element. Most useful with form fields and elements that can gain the keyboard focus (having tabindex for instance). This also disables/enables the elements children, thus enabling the programmer to disable bigger constructs in a single step. It also checks if the element on which it is specified has an attached class instance that supports the `IDsiablable` BK interface, that enables BK components to implement custom disabling if necessary. Disabling an element generally means it will refuse user input, gaining focus and usually also changes the look of the element/component in order to advise the user for the fact. Apparently custom implementations of IDisablable may treat this general guideline in their own manner.

**attributebyparameter**

Sets/gets the value of an attribute of the element. The attribute's name is specified in the binding's parameter. E.g. `data-bind-attributebyparameter="{read path=somepath parameter='title'}"` will set the title of the element like the `elementtitle` operation (see above), but as general attribute - of course this is more useful with some other attributes, especially attributes specific to some HTML elements only. There is something to note here - this sets the attribute and not the corresponding property (if one exists for this type of HTML element). This usually have the same effect, but exceptions are possible and are known to exist in Internet Explorer.

**elementattribute**[]

Like the elementattributebyparameter this operation lets you set/get the value of an attribute but as an indexed target operation. If we reiterate the example above it will look this way with this indexed target operation: `data-bind-elementattribute[title]="{read path=somepath}"`

_Styling operations_

**textcolor**

Sets/gets the color for the text - the same values can be assigned as those one can assing to the [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) style property, e.g. "#FFFF00" or "rgb(120,120,0)" and so on.

**backcolor**

Sets/gets the background color of an element. The colors are like in textcolor. See [background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color) style property for the possible values.

**backimage**

Sets gets the background image url for the element. An url string pointing to the image is specified. As these are most often relative, this will be relative to the base URL of the BindKraft workspace. If unsure what it is open the browser console and check the result of `BKUrl.baseURL();`.

**backposition**

Sets/gets the background position (see the [background-position](https://developer.mozilla.org/en-US/docs/Web/CSS/background-position) style property for the possible values)

**backgrnd**

Sets/gets the entire [background](https://developer.mozilla.org/en-US/docs/Web/CSS/background) style property.

**imgheight**,
**imgwidth**

These set/get [height](https://developer.mozilla.org/en-US/docs/Web/CSS/height) and [width](https://developer.mozilla.org/en-US/docs/Web/CSS/width) style properties of an element respectively. The name img*** can be deceiving - somebody named them that way and backwards compatibility is a bad girl sometimes - they apply to any element, not just to images.

**textalign**

Sets/gets [text-alignment](https://developer.mozilla.org/en-US/docs/Web/CSS/text-alignment) style property

**cssclass**

Sets/gets the value of the class attribute of the element as string.

**addcssclass**[]

Enables the programmer to toggle the existence of certain class in the class attribute of the element. The value assigned must be true or false and the class specified in the index will be added or removed respectively e.g. `data-bind-addcssclass[redish]="{read path=isactive}"`. Here the class **redish** will be assigned if the _isactive_ field in the local data context is true and will be removed otherwise.

**fontweight**

Sets gets the value of the [font-weight](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) style attribute.

**indentination**

Sets/gets the `left-margin` style property in pixels.

**style**[]

If the style related target operations above are not enough, this enables acess to all the style properties, by specifying the style property name as index:
`data-bind-style[text-decoration]="{read path=decoration}"`. It is recommended to use the specialized target operation (if it exists) instead of this one, because some specialized operations do (and will do more in future) some validations and conversions which are not possible in the general target operation `style`.

_Visibility of an element_

**display**[]

Sets/gets the value of the `display` style property. A boolean-like value has to be transferred to the target. The binding will set the value of the `index` if the value is true and `none` if the value is false. E.g `data-bind-display[block]="{read path=isvisible}"` will hide the element if _isvisible_ is false and displayed as block element otherwise. As the HTML progressed the display modes grew and without specifying one it may be too hard or even impossible to determine it if the element is hidden initially. This target operation makes this deterministic. When read (updateSources) the binding will return true if the element is visible even if the current display mode is different from the specified index. This is not typically an issue, but can become if one decides to have multiple such bindings on the same element. This is possible and valid, no matter how unlikely it looks somebody to want to change the display mode that much.

**displaymode**

Sets/gets the value of the `display` style property as string. Usually the visibility is more conveniently controlled through boolean values, but in those cases when the programmer wants to bind the exact CSS values, this can be done through this target operation.

**elementvisible**

Similar to display[], but the mode is not specified. Assigning boolean value will hide/show the element, but if it is initially hidden, an empty string will be assigned to the `display` style property when true is assigned. Although it is often possible to determine the intended display value for when the element becomes visible by analyzing the style and CSS, this can be heavy operation impacting the predictability of the binding's performance with no guarantee for success. Thus we decided to do nothing and effectively assign the default display mode for the given element when the desired one is not known in advance.

**elementvisibility**

Sets/gets the visibility of the element. A boolean value triggers the operation and it changes the visibility style property between visible and hidden respectively.

**elementcollapsed**

Sets/gets the visibility of the element. A boolean value triggers the operation and it changes the [visibility](https://developer.mozilla.org/en-US/docs/Web/CSS/visibility) style property between visible and collapsed respectively. This is useful almost exclusively for tables only.

_Diagnostic and development only_

It is not recommended to use any of the following in production!

**setstyle**

During development it is sometimes inconvenient to change the CSS, but one may still need to apply different styles to an element depending on a boolean value. In such cases **setstyle** can enable the programmer to test logic that in production will use **addcssclass**. This target operation uses the parameter of the binding to set different styles when truthy/falsy value passes through the binding. The syntax is:

```HTML
<p data-bind-setstyle="{read path=somepath parameter='[<truthy styles>][<falsy styles>]}">
```
An example would be something like this:

```HTML
<p data-bind-setstyle="{read path=somepath parameter='[background-color:red;color:white][background-color:white;color:black]}">
```
Obviously this binding is not good for production, but very often designing the CSS can be handled by other team or negotiated with others and this will prevent you from testing some view logic before including the necessary CSS class/classes in the stylesheets. Using **setstyles** the logic can be demonstrated without intruding into the domain of those responsible for the CSS, but do not forget to change it later.


**datacontext**

Reads/sets the data context starting from the element (if any). Will not search for the data context encompassing the element - gets something only if data context is assigned to this element explicitly. Assigning data context will not trigger the (usually expected) processes of update of the bindings down the DOM tree of the template. Can be useful for experimenting, testing and searching for data-bound bugs.

**elementid**

Sets/gets the element id. Using element id-s in BindKraft is a very very bad idea. Almost everything visual one builds with BindKraft is designed to show in multiple instances and any fixed id will violate the uniqueness required by the HTML standards. Still, during development and debugging of elusive problem in a project, assigning id-s to some elements one wants to inspect directly can help a lot. This is reserved for these situations. It is theoretically possible to generate dynamically unique id-s from your classes and assign id-s to elements without causing any troubles, but it is ultimately pointless effort, because its goals can be achieved with much less code by using locally unique `data-key` assignments, access through bindings, assigning sub-components to properties and a number of other techniques.

109 changes: 109 additions & 0 deletions Documentation/Bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Bindings

>For binding syntax reference - [see here](BindingSyntax/BindingSyntax.md)
The bindings are one of the core BindKraft features - a feature that actually gives the name of the platform.

The bindings are used in all BindKraft templates no matter what role the template plays. To give context to this document one can first read about [Templates](Templates.md) and [Views](View.md). In short a template is a piece of HTML containing some special attributes on some of its elements. These attributes are defined by BindKraft and we can roughly separate them into the following categories:

- [**Class specifiers**](BindingSyntax/DataClass.md) - define class from which to create an instance and glue to a given HTML element. Also define parameters for the instance. These are `data-class` and `data-parameters` attributes

- **Bindings** - Define binding objects which will be created by BindKraft and will connect two points/properties of different elements in and "behind" the template. The bindings are two kinds - data bindings and event handling bindings. They are the topic of this document.

- [**Markers**](BindingSyntax/Markers.md) - Various attributes marking elements in a number of ways. They include `data-key` attribute which acts as some kind of local element id, `data-context-border` - explicitly separates the data context under and up the element, `data-async` - contains instructions for asynchronous rendering - needed in big and heavy templates/segments of templates which cannot be separated into something more manageable for some reason (client insistence for example) - enables non-blocking rendering of huge templates which will freeze the browser otherwise.

This HTML piece is processed by BindKraft when it needs to be brought to life and creates a network consisting of DOM objects, your objects (containing your code) and BindKraft built-in objects. The bindings connect them in many ways and transfer data back and forth, route events to their handlers and so on. This network then reacts to everything that happens to it - data changes, UI events and so on and that is the view-level mechanics of BindKraft.

## Data bindings

The general syntax of a data binding looks like:

```html
<div ... data-bind-targetop="{bind source=something path=somepath}"> ...</div>
```
or like this:
```html
<div ... data-bind-targetop[index]="{bind source=something path=somepath}"> ...</div>
```

The right part, the value of the attribute contains a number of settings and forms the `source expression` which is more correctly called `binding expression`, because only part of it is responsible for determining the source of the binding, while the rest are settings concerning the binding functionality in general.

The left part is the part of the attribute name after the `data-bind-` part is sometimes called `target expression`, but is more correctly called `target operation`.

The detailed reference of the right part is in the [Binding expression syntax](BindingSyntax.md) article. That part supports about 20 different kinds of settings which determine where is the source, what [formatters, converters and transformers](Formatters.md) are involved, binding behavior options and so on.

The left part, the `target operation` is much simpler and determines how to link the binding to its target. The `target` is either the HTML element on which the attribute is specified or the instance of a BindKraft class attached to it (with [data-class](BindingSyntax/DataClass.md) attribute).

How they are used is explained in the chapters about [Templates](Templates.md) and [Views](View.md). To provide an idea to the hasty reader, let's give a simple examples:

Once materialized (brought to life) template is usually referred as view (non-official term). Such a view may be a form that shows in a window or piece in another view/template. Most templates that do something usually start with an element that has a `data-class` attribute, thus when materialized they have an initialized and ready to function instance of a BK class. As an old tradition from old technologies some programmers call it "code behind", but this is probably not precise enough with all the nested such pieces we can have.

In such a class an important business logic can be implemented - one that turns the life template into a form or a component, or universally usable control and so on. Considerable part of this is achieved by this code by controlling the bindings in the template - all of them specified on it or (mostly) on its children and their children (and so on).

Having the bindings in place means the code in this object (remember we talk about the root) can get rid of code that reads fields, properties from one place and saves them to another - the bindings will do this wholesale.

For example:
```Javascript
this.updateTargets();
```
will update the targets from their sources for all the data bindings on elements under the root element on which our class is attached.

Another example:
```Javascript
this.updateTargets("flag1|flag3");
```
will update the targets for all the binding under the root which are marked with flag1 or flag3 or both (eg. `data-bind-val="{bind path=something flags=flag3}`). In a complex template updating binding in groups one defines according to the possible changes this can improve the performance drastically.

Another example:
```Javascript
var binding = this.findBindingByName("binding1");
binding.updateTarget();
```
This will find a specific binding marked with a name and will trigger only that binding.

Another example:
```html
<input type="text" data-bind-val="{bind source=myroot path=$myproperty writedata=input}" />
```
This will instruct the binding to listen for the input event on its target and immediately update its source if the event occurs.

If you are new to BindKraft you may have noticed that this means the bindings are mostly triggered explicitly and they can be automatic only if appropriate settings are specified in them. Yes, this is true, but it looks as a limitation only at first glance, having direct control and wholesale or filtered, or individual access to them enables all kinds of tricks which can limit the code needed to couple of lines when simplicity is the goal, or fine tune the updates with more code when the main goal is no performance lost fo unneeded updates. This is a somewhat unusual approach to data binding if compared not only to Javascript data binding oriented frameworks, but also to non-WEB solutions following the data binding road. It is one of the core ideas in BindKraft - make it easy instead of fully automated. The effect is that the programmer can automate the process any way they want and never fall in the sad situation of automation that misses something you need.

### Target operation

It is probably obvious even from the examples that the `target operation` has much simpler and limited syntax compared to the binding expression. The decision to use valid HTML attributes determined a lot about the syntax we can use, which made the value of the attribute the right place for the bulk of the settings, leaving to the target operation only the minimum that is best kept separated for better readability.

The target operation can take the following forms:

data-bind-`targetop`=...

data-bind-`$propertyname`=

data-bind-`targetop[index]`=

data-bind-`$propertyname[index]`=

The forms with square brackets [ ] in them are indexed forms and the index is usually rather a key - textual key.

The forms that start with $ are references to pseudo/active properties on the attached BindKraft object. They can be non-indexed or indexed as can be seen from the example above.

#### data-bind-`targetop`=...

This form refers to one of the built-in BindKraft target operations. They all act on the DOM element to which the attribute belong. The list of the supported operations and details about them is in [Supported target operations](BindingSyntax/targetops.md).

For a quick idea what they do, here are a few examples:

```html
<span data-bind-text="{read path=caption}"></span>
```
This one sets the text in the span element from the field "caption" in the local data context.

```html
<input type="text" data-bind-val="{bind path=caption}"/>
```
This one sets/gets the value of a text field input element.


## Event handling bindings


181 changes: 165 additions & 16 deletions Documentation/BkInit.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
# BkInit - initialization helpers
<!-- vscode-markdown-toc -->
* 1. [BKInit - shortcuts](#bkinit---shortcuts)
* 1.1. [BKInit.StartMenu](#bkinit.startmenu)
* 1.2. [BKinit.SystemMenu](#bkinit.systemmenu)
* 1.3. [BKInit.DevMenu](#bkinit.devmenu)
* 1.4. [BKInit.PrivateMenu](#bkinit.privatemenu)
* 1.5. [BKinit.AppMenu](#bkinit.appmenu)
* 1.6. [BKInit.KeylaunchMenu](#bkinit.keylaunchmenu)
* 1.7. [BKInit.RecentMenu](#bkinit.recentmenu)
* 2. [CL scripts (non-shortcut)](#cl-scripts-(non-shortcut))
* 2.1. [BKInit.MasterBoot - the most important setting](#bkinit.masterboot---the-most-important-setting)
* 2.2. [BKInit.ModuleScript](#bkinit.modulescript)
* 2.3. [BKInit.commands](#bkinit.commands)
* 2.4. [BKInit.urlCommands](#bkinit.urlcommands)
* 2.5. [(deprecated) BKInit.commandUrlAliases](#(deprecated)-bkinit.commandurlaliases)
* 2.6. [(deprecated) BKInit.commandUrlAlias](#(deprecated)-bkinit.commandurlalias)
* 2.7. [(deprecated) BKInit.commandUrlGlobal](#(deprecated)-bkinit.commandurlglobal)
* 2.8. [BKInit.AppData](#bkinit.appdata)
* 2.9. [BKInit.AppInfo](#bkinit.appinfo)
* 2.10. [BKInit.WorkspaceName](#bkinit.workspacename)
* 2.11. [BKInit.WorkspaceName](#bkinit.workspacename-1)
* 2.12. [BKInit.Translation](#bkinit.translation)

<!-- vscode-markdown-toc-config
numbering=true
autoSave=true
/vscode-markdown-toc-config -->
<!-- /vscode-markdown-toc --># BkInit - initialization helpers

These helpers are intended to be used in the `init.js` files of modules.

@@ -10,9 +37,9 @@ Project construction and configuration guide (_TODO: put a link here when the ar

Last update for version: 2.17.5

## BKInit - shortcuts
## 1. <a name='bkinit---shortcuts'></a>BKInit - shortcuts

### BKInit.StartMenu
### 1.1. <a name='bkinit.startmenu'></a>BKInit.StartMenu

Manages shortcuts in `shellfs:startmenu`. The shortcuts in this directory are usually shown by the system's shell UI (NotchShell being an example shell) and other apps that want to display the official start menu. Almost the same syntax is also used for other directories containing shortcuts (except the BKInit's method everything else is the same).

@@ -66,30 +93,152 @@ BKInit.StartMenu(function (menu) {
};
```
### BKinit.SystemMenu
### 1.2. <a name='bkinit.systemmenu'></a>BKinit.SystemMenu
(TODO: write this section)
### BKInit.DevMenu
### 1.3. <a name='bkinit.devmenu'></a>BKInit.DevMenu
### BKInit.PrivateMenu
### 1.4. <a name='bkinit.privatemenu'></a>BKInit.PrivateMenu
### BKinit.AppMenu
### 1.5. <a name='bkinit.appmenu'></a>BKinit.AppMenu
### BKInit.KeylaunchMenu
### 1.6. <a name='bkinit.keylaunchmenu'></a>BKInit.KeylaunchMenu
### BKInit.RecentMenu
Syntax:
```Javascript
BkInit.KeylaunchMenu(function(menu) {
menu.add("E","launchapp MyApp");
});
```
Enables you to add shortcuts to `shellfs:/keylaunch` directory. This directory is internally used by the system and executes shortcuts in response to `Ctrl+Alt+{letter}` keyboard combination. Keep in mind that `letter` cannot be everything - some are reserved by the browser (may differ between browsers - test it first). These shortcuts are supported for developer's convenience - when there is no place for a launching UI or running support apps. It is recommended to not overuse this in production as it can scare the end users.
### 1.7. <a name='bkinit.recentmenu'></a>BKInit.RecentMenu
## 2. <a name='cl-scripts-(non-shortcut)'></a>CL scripts (non-shortcut)
### 2.1. <a name='bkinit.masterboot---the-most-important-setting'></a>BKInit.MasterBoot - the most important setting
Lets you specify the boot CL script. This script is executed immediately after all the specified Javascript code is loaded (see the notes a bit later).
Syntax:
```Javascript
BkInit.MasterBoot("startshell \
createworkspace 'bindkraftstyles/window-workspacewindow-withshell' \
initculture 'en' \
initframework \
inithistory \
launchone NotchShellApp \
launchone WelcomeApp \
runurlcommands \
")
```
The example script above is from early version of KraftApps. The initial 4 statements are virtually mandatory for all BindKraft setups with possible variations of the arguments (current and future). More details and what they do is a topic for the [Boot process](BootProcess.md) article.
This BkInit setting is usually found only in the startup modules (colloquially called WebSite or Workspace modules). To be precise the boot script has a pre-defined name - "**boot**" and must reside in the root of the `boot fs` (which is formally refered to this wat `bootfs:/boot`). When all the system preparations are done BindKraft executes this CL script.
This allows (as with all the other BkInit settings) the script to be rewritten by the different modules and the last one to remain the actual file that will be executed. BkInit is intended for use during the loading phase and before initializing the system. BkInit contains handy means to write settings into the memory - mostly in the memory FS, but in some other places as well. The BK modules load in their dependency order, which guarantees that the startup module will be loaded last and its version of the boot script will take effect instead of any others. This enables a very simple technique - each module can specify such a script - designed for the scenario where it will run alone, with its dependencies only. This is convenient for development time where running all the apps from all the modules is not always useful or even desired.
### 2.2. <a name='bkinit.modulescript'></a>BKInit.ModuleScript
Syntax:
```Javascript
// Syntax:
BkInit.ModuleScript(modulename, function(scripts){
scripts.write(filename, script, appclass);
})

// Example:
BkInit.ModuleScript(modulename, function(scripts){
scripts.write("clscript1","launchapp App1 launchapp App2");
});
```
**modulename** - The name of the module. This translates to a subdirectory in the root of `bootfs:` with that name (e.g. bootfs:/mymodule).
**filename** - The file name for the CL script. E.g. if the script is named "myscript" this will create file with the CL in `bootfs:/mymodule/myscript`.
**script** - The content of the CL script
**appclass** - Optional class name of the app launched by the script (if any). This is useful in some circumstances, but is otherwise optional. This property is heavily used by the shell when it displays launch menu(s) with shortcuts which are CL scripts with added icon and description. Knowing what app is started by the script it can show useful tracking information. In raw CL scripts this is useful mostly if you have intention to do something along these lines too.
**What this is and can be used for?**
Module scripts go into the bootfs which is a good hint already. Some modules may include series of apps or/and apps with internal commands. This can go even further - some modules may want to "prepare" the workspace in some manner and then launch an app (or more than one app). Thus by convention any number of predefined scripts can be stored by a module in a subdirectory of the bootfs. They will NOT be used for anything by default, but in the MaserBoot script they can be easily called during the workspace boot process. To call the example script file above we have to include in the master boot gcall 'mymodule/myscript'.
So, this can be viewed as ready to use scripts for various configurations/scenarios specific to a module offered as files prepared by the module's developer (usually) and placed in a convention defined location. Then some of them can be quickly included in the boot process if and when needed by the person who configures the whole workspace/web site and achieve certain effect. The fact that the developer(s) of the module know best their product makes it reasonable for them to place several scripts for specific modes/configurations and scenarios they want to make optionally available for workspace initialization.
This can go much further in more complex web sites - e.g. the directories can be enumerated and scripts with certain names executed if present. This will effectively implement a very simplified imitation of a classic unix boot process - a simple way to configure the environment for different behavior without the need to dig too deep into app documentation for arguments, supported commands and so on.
## CL scripts (non-shortcut)
### 2.3. <a name='bkinit.commands'></a>BKInit.commands
### BKInit.MasterBoot - the most important
### 2.4. <a name='bkinit.urlcommands'></a>BKInit.urlCommands
### BKInit.ModuleScript
Configures commands that can be executed during the workspace initialization in response to certain URL query parameters. See [BKInit.urlCommands](BKInit_urlCommands.md)
### BKInit.commands
### 2.5. <a name='(deprecated)-bkinit.commandurlaliases'></a>(deprecated) BKInit.commandUrlAliases
### BKInit.commandUrlAliases
### 2.6. <a name='(deprecated)-bkinit.commandurlalias'></a>(deprecated) BKInit.commandUrlAlias
### BKInit.commandUrlAlias
### 2.7. <a name='(deprecated)-bkinit.commandurlglobal'></a>(deprecated) BKInit.commandUrlGlobal
### 2.8. <a name='bkinit.appdata'></a>BKInit.AppData
```Javascript
BKInit.AppData(AppName, function (data) {
data.content("contentname", optionalcontenttype,content);
data.object("filename", {... something ...});
data.folder("foldername1");
data.folder("foldername1/foldername2");
};
```
Adds a memory "file" to the `appfs:` for the specific app. `AppName` must be the name of the app's main class (_the class instead of the name can be used as well_). Internally this creates in appfs: a directory for your app and puts content under it (including sub-folders if created)
Both `content` and `object` methods take as first argument the name of the memory file. That name can start with a subdirectory path eg. `"settings/devices"`, the subdirectory must exist.
To create a directory, use the `folder` method.
### 2.9. <a name='bkinit.appinfo'></a>BKInit.AppInfo
```Javascript
BKInit.AppInfo(AppName, function (data) {
data.content("contentname", optionalcontenttype,content);
data.object("filename", {... something ...});
};
```
### 2.10. <a name='bkinit.workspacename'></a>BKInit.WorkspaceName
```Javascript
BKInit.WorkspaceName("My magical set of apps");
```
### 2.11. <a name='bkinit.workspacename-1'></a>BKInit.WorkspaceName
```Javascript
BKInit.WorkspaceName("My magical set of apps");
```
Sets the workspace name, accessible through System.set/get_`workskapceName`
### 2.12. <a name='bkinit.translation'></a>BKInit.Translation
```Javascript
BKInit.Translation("MyClass", function(trans) {
trans.add("en", {
caption: "My great app",
confirmBtn: "Confirm",
cancelBtn: "Cancel"
});
trans.add("bg", {
caption: "Моята страхотна апликация",
confirmBtn: "Потвърди",
cancelBtn: "Отказ"
});
}
```
### BKInit.commandUrlGlobal
A simple way to add translations of short texts to the system. This approach is mostly for development time, the translations for production should be loaded from NodeSets, see `loadtranslation` and `loadtranslations` commands.
52 changes: 49 additions & 3 deletions Documentation/BootProcess.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,54 @@
# Boot process

This document describes the current boot process - ordering, recognized elements and start/boot scripts
This document describes the current boot process of a BindKraft project/web site.

## Scripts
To get to this point we have to construct the project, put all the BindKraft (BK) modules we need, fiddle with their dependencies if necessary and pay special attention to the `start up` module (This is described in detail in the previous document).

Although this may repeat some topics covered in the [BindKraft Project Construction](BKProject.md) they play integral part of the boot process and we have to point them out briefly:

## Before we start with the process

### The startup BK module

The `start up` BK module pulls the rest through its dependencies on them. Depending on the backend used this may be done ahead of time using CLI script or on server start (CoreKraft for example) or in some way that combines both. As mentioned before only the Javascript files have to be loaded in exact order of the BK module dependency chain and according to the #using directives in the *.dep files on BK module level. This is usually done for you by the tool/server software and one needs to deal directly with this problem only if they are building new tools for building/running BindKraft projects.

### init.js files

Thanks to the deterministic loading order of the Javascript files BindKraft uses a simple, but effective trick to build the in-memory configuration/state of the project. While the files load pieces of script can be executed while loading in order to record various configuration data in well-known places in memory.

Because of the order defined by the BK module dependencies and the pre-defined and (known) locations where these settings go, they can be replaced by scripts that load later. This is very useful when modules define default settings - if they need a change it can be applied in a BK module that depends on them and ultimately in the `start up` module.

The possible settings are many and serve a long list of functionalities, API and commonly used utilities. Some are indeed defaults for which it is best to pack them in the BK module that also carries the implementations that use them. Others are more project related and the best approach to them is to configure for each project and not as defaults. The dependency determined loading order and API for setting them during load and boot serves both purposes well.

As a **convention** each module should include an **`init.js`** file, preferably as last file included in the BK module. In this file all the defaults and other setting should be applied to the system. This way one can trace and maintain the way the project is configured by inspecting the `init.js` files of all the project's BK modules, considering the order in which they are loaded - defined by _Dependency.json_ files.

In the `init.js` files almost all of the settings are set by using the [BkInit](BkInit.md) API - exclusively built for that purpose and the defaults management methods of [Class](CoreClasses/Class.md) utility set (mostly Class.defaultsOf - a BkInit API will be added for this in order to streamline the process further).

Looking back at the startup module - this makes it the knot that holds the whole system together and the final authority for configuration and initialization. Its `init.js` file sometimes is the only real content in the module. It is the last file to load before the project starts to run and this makes it the perfect place to specify the settings that will actually apply to the project.

## The boot process

## Loading (loading phase)

As said above and in the project construction guide the Javascript files load in order defined by the BK module dependencies and then the #using directives inside the modules (in the *.dep files).

During that phase all the classes, interfaces, enums and other structures get defined.

All the `init.js` files are processed during loading. They all (must) use features available at this phase - BkInit API is designed for this and anything done through it is compatible with the loading phase. The init.js files sometimes need to use definitions from their module - that is why it is strongly recommended to include them as the last Javascript file in the BK module. We will refer to the particular BkInit API below while we describe a feature that depends on settings managed through it.

### Spotting coding errors

The loading phase can be called also "compilation" phase from the programmer's point of view. The OOP declarations are processed at this time and any errors are logged through the so called **CompileTime** object. It is not a normal part of the system and it is fully functional only in this phase. Its purpose is to collect the messages issued during loading and provide them to any subscribed viewers/further loggers. While developing it is important to look at the console window for warnings and errors being reported. More about this can be found in a separate document.

When loading finishes BindKraft launches the registered code analysis procedures and they might log more error and warning messages concerning the code if they find problems. These procedures should be disabled on production environments, because they are expected to grow and even now they add noticeable delay on start up.

## Booting

Now that the code is loaded and processed comes the moment to really boot the system. This involves initializing the required structures, launching the autostart apps, executing variety of scripts that will bring the workspace to the desired initial state.

### Execute the bootfs:/boot

TO DO:

## Procedure

@@ -15,7 +61,7 @@ This document describes the current boot process - ordering, recognized elements

## Elements

### URL scripts
### URL commands

Current implementation expects them as query parameters

2 changes: 2 additions & 0 deletions Documentation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -12,3 +12,5 @@
11: Added property stubbing routine as static method of Delegate.
Added BaseObject.LASTERROR static method that works just like the instance one.
Corrected and styled minimally the MainWindow's final fall-back template (in code).

TODO: update this file - use the release notes.
39 changes: 39 additions & 0 deletions Documentation/Connectors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Connectors

Connectors are classes inheriting from `Connector`. They provide a "connection" abstraction which is most often perceived as _fetching data_ abstraction (the reason why will get clear further in the document).

A connector is composed of a few parts common for all the connectors no matter what they do:

>**address** - a string representing the location of the data
>**host** - also called bind host. An instance of a class that gives a starting point for the address or/and defines the context needed for the connection
>**options** - Several possible options, not specific to a given connector type, but not necessarily supported by all connectors.
>**parameters** - An indexed property gives access to a single dictionary of parameters. It may or may not be used by each connector type. Parameters are useful, _but they usually limit the connector's abstraction - e.g. the option to use a different connector with the same component_.
The above list basically begins to describe the purpose of the connectors - to represent the way to fetch (and store when supported) some data/resource with a few standard components:

- the type of the connector (a string or class)

- the address of the connector (a string)

- the host (can be null for some connectors)

Over that some additional adjustments can be made, but they will limit the variety of connectors one can interchangeably use:

- parameters - for example they can be filter parameters for DB query or in-memory data filter etc.

- options - instruct the connector how to perform its operation. They are designed to be as independent of the implementation as possible, but this has limits too, so options will most often presume requirements not all connectors can meet.

## Operation procedure with connectors

The minimal needed knowledge about a connector is basically two strings (the type of the connector and the address) - these can be changed together.

The host is determined by design by the client of the connectors. The host may or may not be able to provide the context needed by the connector being specified (through its type name for instance), but this is one of the vectors for improving a component that acts as a host - implement more features that different connectors need. This will enable the component to support more connectors and consequently more kinds of sources for the data it needs.

So, for a code that is using connectors the steps are:

**First step** - Obtain the connector from somewhere or alternatively create it and set the address and the host.

TODO: continue the document.
34 changes: 34 additions & 0 deletions Documentation/Conventions/URLUsage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# URL usage conventions in BindKraft

While not absolutely mandatory these conventions correspond to the way certain BindKraft APIs work. Violating the conventions is possible, but requires good knowledge of the affected functionality.

## URL real estate separation.

_More information about the URL structure can be found in the documentation for BkUrl._

URL general structure

```
<bk-preffix>:<schema>://<authority>/<path>?<query parameters>#<fragment>
```

**bk-preffix**

Supported by some BindKraft API to enable option to specify post/get verb as part of the URL and avoid the need of additional argument. Basically this is necessary when the URL can be specified in the HTML markup.

**schema**

The standard URL schema. No special usage in BindKraft. It should be http or https. Pseudo-schema names could be introduced in future.

**authority**

Projects using sub-domains may use part of it, but this is typically a project specific implementation.

**path**

If we describe the path as prefixes and the rest of the path:

```
<prefix1>/<prefix2> ... <prefixN>/<rest of the path>
```

5 changes: 4 additions & 1 deletion Documentation/CoreClasses.md
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
## Core features

[BaseObject class](CoreClasses/BaseObject.md) - the root most class
[Class - type manipulator](CoreClasses/Class.md) - Static set of methods for type checks/queries and more.

### Delegation and events

@@ -49,7 +50,9 @@

[TemplateConnector](CoreClasses/TemplateConnector.md)

## Geometry helpers
## Geometry helpers (deprecated)

New classes in the [ViewClasses](ViewClasses.md) scripts/view/geometry replace the old ones. The new classes will work with the old ones where appropriate, but new code should use the new classes!.

[Point](CoreClasses/Point.md) | [Rect](CoreClasses/Rect.md) | [Size](CoreClasses/Size.md) | [SizeLimits](CoreClasses/SizeLimits.md)

42 changes: 41 additions & 1 deletion Documentation/CoreClasses/BaseObject.md
Original file line number Diff line number Diff line change
@@ -53,10 +53,50 @@ These are available on all classes in BindKraftJS through inheritance unless ove

**Last error report and management**

### BaseObject.prototype.LASTERROR

```Javascript
BaseObject.prototype.LASTERROR(code, text, method);
```

Behaves like the static version, but when called with arguments sets the className to the name of the class of the current object.

See [Using LASTERROR](lastError.md)
See [Using LASTERROR](lastError.md)

### BaseObject.prototype.equals

```Javascript
BaseObject.prototype.equals(obj)
```

**obj** - object to compare with this one.

`obj` can be null or of a type that does not inherit from BaseObject (i.e. string, number etc.). The method returns `true` if the object is considered equal to this and `false` otherwise.

BaseObject's implementation will check id `obj` is null and return false immediately, then if obj is not null it will it with `this` using `==` and return the result.

Inheriting classes may choose various comparison strategies depending on the philosophy of the class hierarchy being built. Yet in almost all cases the implementation can simply first call BaseObject's implementation, thus ensuring the border cases are checked and then continue with the comparison. Example:

```Javascript
MyClass.prototype.equals = function(obj) {
if (MyBaseClass.prototype.equals.call(this, obj)) return true;
if (BaseObject.is(obj, "MyClass") &&
obj.$someprop == this.$someprop) {
return true;
}
return false;
}
```

The example considers the two objects equal based on single property, but after calling the parent class implementation first. If the BaseObject's implementation was not overriden it will do what was said above. On the other hand if it is overriden it may decide the objects are equal on more basic principles.

In practice comparison in a class hierarchy is more often negative - the base class may find objects non equal on more general principles and only if it considers them equal there will be reason to continue and check if the added features in the child still allow them to be considered equal.

How useful is this?

- Array has the added BindKraft methods `findElement`, `getElement`, `removeElement`, `replaceElement`, `addElement`, `insertElement`, `lastElement`, `addElements` that will enable only unique elements to be added to the array (providing the developer does not use any other methods to manage it). This is based on the `equals` method.
- Delegate will compare its instance and method thus helping EventDispatcher (for instance) to recognize the handler even if the Delegate's instance is different

and there are many others.


61 changes: 61 additions & 0 deletions Documentation/CoreClasses/ChunkedOperation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# ChunkedOperation

This class inherits from Operation and is a fully functional operation, but in addition it is capable of reporting "chunks" of the work being done. Chunked operations are used in all cases where the task performed should be seen not just as an operation that starts and completes, but also as intermediate reports - between the start and the completion.

This abstraction fits (probably unexpectedly) many cases - from dialogs that apply settings and the user can apply changes multiple times before completing the dialog, to scenarios where progress is reported, to scenarios where this mechanism is used as means for constant communication with some object for its entire lifetime. Changing a little the way one views certain events can quite often put them into the category for which chunked operations are simple and convenient way to track process, state, chain of actions and so on.

## Declaration

```Javascript
function ChunkedOperation(taskproc, timeout);
ChunkedOperation.Inherit(Operation, "ChunkedOperation");
ChunkedOperation.Implement(IChunkedOperationHandlingCallbackImpl);
ChunkedOperation.prototype.ReportOperationChunk(success, errorinfo_or_data);
ChunkedOperation.prototype.chunk(callback, callbackfail);
```

Interfaces implemented:

IChunkedOperation, IChunkedOperationHandling, IOperation, IChunkedOperationHandlingCallbacks, IOperationHandling, IOperationHandlingCallbacks, IOperationReset

## Members

**ChunkedOperation.prototype.chunk(`callback`, `callbackfail`);**

Sets a callback to receive chunk reports.

**callback** - A callback (function, Delegate, EventDispatcher or any IInvokeWithArrayArgs object). The callback has the following prototype:

```Javascript
function(success, data)
```
The callback can return `false` to force the operation to complete (unsuccessfully) and no more chunk results will be reported. Any other return value will be ignored.

When success is false the `data` contains an error (string).

**callbackfail** - optional second callback, If specified all successful chunks will be reported to the first (`callback`) and all non-successful to the second (`callbackfail`). The success argument will still be passed to both.

What is successful chunk and what is non-successful is up to the code that calls `ReportOperationChunk` and corresponds to the specifics of the task. In other words this is up to the programmer who decided to use this approach.


**ChunkedOperation.prototype.ReportOperationChunk(success, errorinfo_or_data);**

Used by the other side to report chunks of data (work done). It follows the same pattern as CompleteOperation and has two arguments:

**success** - `true` reports successful chunk and data should contain the reported data. `false` reports un-successful chunk and data should contain error info (preferably string message).

**data** - (errorinfo_or_data) - the data or error being reported.

Obviously applying the chunked operation abstraction in all kinds of scenarios means that in some of them there is no possible meaning to assign to successful and non-successful chunks and they are all just successful. There is nothing wrong with that, the separation of hte chunks into successful/non-successful is just an option the programmer can use when it makes sense and ignore otherwise.

## Remarks

At the moment of writing there is no mechanism similar to `whencomplete()` for reporting chunks. Therefore, without additional effort to implement this in your own callback only one (two if separate are defined for successful/non-successful) callback can receive the chunk reports. It seems logical to keep it that way, because the chunks are more or less a way to abstract progress into workable pieces of data. This implies the chunk data is likely to be processed by the callbacks and applied to something in a very intentional manner. I.e. the abstraction that chunked operations define seems to be an intentional task execution with funneling the chunks done into the purpose for which this was done in the first place. Reporting them to multiple listeners may look tempting, but in most cases they will have very different reasons to do so and very different use for the data - the purpose of the data is usually fully known only for the code that starts the task and any other listeners will likely need some filtered/transformed data - adapted to their function.

It is important to distinguish between `completion` of an operation and `intermediate progress` chunks. The completion of an operation is interesting for potentially many parties, most of them interested in the completion, but not in the specific data in order to achieve synchronization. Unlike completion the intermediate progress does not signify such an universally recognizable event and the data it carries is what makes it useful, which in turn relates this usefulness to the "understanding" of the data (remember successful chunk is arbitrary and meaningful only in the specific scenario implementation).

This is the reason for not including a ready-to-use mechanism to broadcast chunks to many parties, we fear that this can lead to mistakes and possibly to attempts to use the chunks as some kind of "sub-operations" which will be wrong.




47 changes: 31 additions & 16 deletions Documentation/CoreClasses/Class.md
Original file line number Diff line number Diff line change
@@ -33,21 +33,33 @@ The above example checks if certain class supprts `IFreezable` interface (1) the

### Class.implementors(iface)

### Class.funcDoc(func)
Returns an array of the class names of all the classes that support the `iface`.

### Class.getInterfaceDef(iface)
### Class.funcDoc(func) (currently out of sync)

### Class.getInterfaceName(iface)
### Class.getInterfaceDef(iface) from v2.7.0

### Class.doesextend(iface1, iface2)
Returns the definition (the type) of an interface or null if it does not exist.

### Class.doesexextendedInterfacestend(iface)
### Class.getInterfaceName(iface) from v2.7.1

### Class.extendedInterfaceDefs(iface)
Returns the name of the interface or null if it does not exist. Even if you have the name, you can check if it is valid this way.

### Class.isrequestable(iface)
### Class.doesextend(iface1, iface2) from v2.7.1

### Class.typeKind(def)
Checks if `iface1` extends `iface2` and returns true or false.

### Class.extendedInterfaces(iface) from v2.7.1

Returns an array of the names of all the interfaces extended by `iface` directly or indirectly.

### Class.extendedInterfaceDefs(iface) from v2.7.1

Like `extendedInterfaces`, but returns array containing the definitions (types) instead.

### Class.isrequestable(iface) from v2.7.1

### Class.typeKind(def) from v2.18

### Class.getClassDef(cls)

@@ -57,19 +69,22 @@ The above example checks if certain class supprts `IFreezable` interface (1) the

### Class.supportsMethod(type, member)

### Class.getClassName(cls)
### Class.getClassName(cls) from v2.16.3

### Class.defaultsOf(cls) from v2.7.3

### Class.defaultsOf(cls)
### Class.classDataOf(cls, dataType) from v2.18

### Class.classDataOf(cls, dataType)
### Class.interfaceDataOf(cls, iface) from v2.18

### Class.interfaceDataOf(cls, iface)
### Class.classes([filterproc]) from v2.15

### Class.classes([filterproc])
### Class.returnTypeOf(def, method) from v2.18

### Class.returnTypeOf(def, method)
### Class.argumentsOf(def, method) from v2.18

### Class.argumentsOf(def, method)
### Class.argumentOf(def, method, index) from v.2.18

### Class.argumentOf(def, method, index)
### Class.chunkTypeOf(def, method) from v2.18.5

### Class.eventArgumentsOf(def, eventname) from v2.18.5
104 changes: 104 additions & 0 deletions Documentation/CoreClasses/EventDispatcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# EventDispatcher class

Provides direct `event` emission functionality in BindKraft. Emitting or firing an event is the act of calling all the subscribers one after another.

Subscribing for a EventDispatcher is done through its `add` method or by `data-on-$` bindings, or by using `readdata`/`writedata` binding entries and listing a reference to an EventDispatcher based event source.

Classes implement `events` by exposing members that hold an instance of an EventDispatcher. The name of the event is the name of the member. When created the EventDispatcher instances receive through their constructor a reference to the instance of the class that implements `event` using the EventDispatcher.

Having a reference to their host instance enables the EventDispatcher to automatically be aware of its state and modify their behavior somehow. While classes derived from EventDispatcher can use this in an arbitrary ways, the EventDispatcher class itself implements functionality that takes into account the `freeze` state of its host (if the host supports `IFreezable` interface).

`Freezing` is a technique that enables a mode in which events are not fired (emitted). This is useful in various scenarios, but most prominent one concerns the classes derived from `Base` class that serve as UI components. During their initialization they usually need to suspend the event firing until their initialization is complete and the view or other component in which they reside is also fully prepared for normal function.

## Initializers

`InitializeEvent` initializer is the preferred way to define events in BindKraft classes. The declaration is as simple as:

```Javascript
MyClass.prototype.someevent = new InitializeEvent("Description of the event");
```

Each instance of MyClass will have the `someevent`. In addition this initializer supports the Arguments method:

```Javascript
MyClass.prototype.someevent = new InitializeEvent("Description of the event").Arguments(ISomeInterface, null, ISomeOtherInterface);
```

The Arguments method is needed when declaring interfaces extending `IManagedInterface` to be used through LocalAPI or for inter-app communication. These techniques use proxies instead of exposing references to the classes passed as arguments and need an interface definition (that extends IManagedInterface) in order to be able to build a proxy, thus Arguments method of the initializer enables declaration of the interface that will be exposed for an object argument. The object passed in that argument place will be required to support the specified interface. Any positions for simple value arguments or plain object arguments are marked with `null`. In scenarios not involving LocalAPI or inter-app communication usage of the Arguments is not necessary.


## Implemented interfaces

IInvocationWithArrayArgs, IInvoke, IEventDispatcher

## Constructor

`new EventDispatcher(host[, translator])`

**host** - the object that owns the dispatcher and uses it as an event emitter. It is recommended to use the InitializeEvent initializer described above, but if this is inappropriate for some reason the usual routine is to create event dispatcher like `this.myevent = new EventDispatcher(this)`.

**translator** - optional argument equivalent to the property `set_translator`.

## Properties

### `get/set_adviseNewComers` boolean, default: false

A `boolean` property with default value of `false`. When set to `true` it instructs the dispatcher to implicitly call (advise) any newly registered subscribers with the last event (invocation) that happened before their registration. This is especially useful when synchronization issues has to be easily resolved when there is a chance that subscriber may be late for an event.

### get/set_translator

This property is not typically used in normal application code. It is for usage by the proxies used by the local service feature of BindKraft. They will use it internally to create proxy dispatcher and configure the to "translate" invocation arguments by creating automatically proxies for them when necessary.

While translators can be used for other purposes it is not a recommended practice, because this would involve unnecessary complexity for the almost any imaginable scenario - i.e. such a need would be most likely a result of bad planning.

## Methods

### reset()

Resets the state of the dispatcher (does not remove handlers). If the dispatcher has been invoked (fired) before this state is cleared (see adviseNewComers above).

### set(...arguments...)

Sets the "happened" state of the dispatcher. The dispatcher is not fired (invoked), but its state is set as if it was fired with the arguments passed to the `set` method. New subscribers will be advised for this "faked" event.

### isFrozen()

Returns a boolean indicating of the underlying host of the dispatcher is in frozen state.

### add(handler, priority)

Subscirbes the `handler` for the event implemented with this EventDispatcher.

**handler** - can be a function, a `Delegate` or any object of a class supporting the `IInvocationWithArrayArgs` interface. Most classes that implement `IInvoke` also implement `IInvocationWithArrayArgs`, but latter is chosen as it can provide invocation with both the `invoke` and the `invokeWithArgsArray` methods.

**priority** - optional value that determines the order of the handler among all the subscribers. Can be boolean, number or null and undefined. Handlers registered with priority of:
`true` - Are invoked first. All handlers registered with `true` are not guaranteed to be invoked in any particular order among themselves and any observed behavior should not be considered applicable in future versions.
`false`, null, undefined - Are invoked last - after all other handlers in no guaranteed order among the other handlers registered with `false`. null and undefined are equivalent of `false`.
`number` - Are invoked after all the handlers registered with `true` and before all the handlers registered with `false`. The handlers registered with a numeric priority are invoked in order corresponding to the number in rising order, thus a handler registered with 0 will be invoked before handler registered with 10.

### remove(handler)

Removes a handler by comparing it to the registered subscribers. The most secure way is to remove a handler by passing a reference to the same handler that has been subscribed with `add`. Any subscribers derived from BaseObject will be compared according to their `equals` method and allow more flexible management - check how the equals works in the handlers you register to find out if it is possible to remove them by using convenient comparison.

For example `Delegate` class implements equals in a way that treats instances pointing to the same object and same member as equals and ignores any bound arguments while comparing them. The most convenient way to implement methods that will handle events is to use the `InitializeMethodDelegate` or `InitializeMethodCallback` initializers.


### removeByTarget(target)

A method with limited usefulness. Remove the handlers registered by a certain instance. In order this to work the registered handlers has to support the `ITargeted` interface (Delegate being the most popular case). Thus plain functions will not be affected even if they are wrappers of a Delegate. Still in certain well-thought usage scenarios this allows bulk management.

### removeAll()

Removes all the subscribers, but does not affect the "happened" state.

### invoke(... arguments ....)

Fires (emits) the event by calling/invoking all the subscribers with the specified arguments. The order of invocation is according to the priority parameter in the `add` method. Also this methods sets the dispatcher "happened" state so that new registrants can be also invoked with these arguments if the `adviseNewComers` property is set.

### invokeWithArgsArray(args[])

Like the `invoke` method, but takes the arguments as an array instead.

### getWrapper()

Returns a plain Javascript function that when called will invoke the dispatcher with the arguments passed to the function. This is especially useful when BindKraft events have to be fired by external for BindKraft facilities (like DOM events for instance) or code that is unaware of the fact that a function it calls is actually an event dispatcher (emitter).
27 changes: 27 additions & 0 deletions Documentation/CoreClasses/ILocalProxyCollection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ILocalProxyCollection

## Interface declaration

```Javascript
function ILocalProxyCollection() {}
ILocalProxyCollection.Interface("ILocalProxyCollection","IManagedInterface");
ILocalProxyCollection.prototype.count();
ILocalProxyCollection.prototype.item(index);
```

### count()

Returns the number of items in the collection.

### item(index)

Returns the item indexed by the `index` argument. If `index` is out of the collection bounds ( `index < 0 or index >= collection.count()`) null will be returned.

### Remarks

This interface is what the caller will receive in response to its call (directly or through operation depending on the method's design). The collection is read-only for the caller.

In order to have a method that returns it one has to declare it with `.ReturnType(ILocalProxyCollection)`.

It can be used also as an input parameter when calling a method through a proxy. If this is allowed the method have to specify this type in the `.Arguments` declaration.

150 changes: 150 additions & 0 deletions Documentation/CoreClasses/LightFetchHttp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# LightFetchHttp class

Enables AJAX requests to be sent to the origin and other servers. It works with xmlHTTPRequest in the background and is designed for `reuse`. I.e. Instead of creating new instance for each new request that has to be sent an instance that is no longer needed for anything else should (when possible) be reused.

The reuse of the object can be achieved on different levels - from full reset and change of all parameters to keepint most of the parameters intact and making new requests passing only the specific components of the requests.

The class supports `plugins` that can impact the request preparation to some extent (_further development will extend further their options to apply changes_).

The class follows the philosophy of the "expected response type", which means the responses are expected to return the specified kind of response (see `get/set_expectedContent` property).

The class uses body encoders to encode the request body (for the methods that support bodies). They are both built-in and custom. The latter are set as callbacks (wither delegates or functions) - see `get/set_postDataEncode` property.

## Notes about usage and future development

`LightFetchHttp` class is intended as low level replacement for all other AJAX means of communication in BindKraft. While it is not forbidden or impossible to use other libraries or direct API calls for AJAX requests, LightFetchHttp is going to provide better integration with BindKraft in general and with specific features in particular.

In near future a communication pipeline based on this class will replace the old one - accessible through `ajaxGetXML/ajaxPostXML` methods of all classes. This will make dealing with it mostly indirect with very low number of cases in which the programmer will have to know anything about `LightFetchHttp` and the related classes. The ajax methods will be removed from [BaseObject](BaseObject.md) and will be put into easy to use `implementers` which can be included in any class that needs the feature.

This approach will make the legacy compatibility break very easy to fix and will allow new projects to avoid the old-fashioned ajaxGetXMl/ajaxPostXML in favor of more convenient new implementations or mix old and new together when needed.

Direct usage of the class is Ok, of course, but we aim at almost eliminating the need to do so. The direct usage can be a little cumbersome compared to the integrated pipelines (the mentioned implementers) or Connectors based on it, but it is still easier than raw usage of xmlHttpRequest and fetch, especially when integration with BindKraft features is needed (e.g. auto-using a Bearer token per URL, following result structure for direct use with other BK functions, auto-encoding of data for CoreKraft nodesets and so on.)

## Properties

### **httpuser**

### **httppass**

### **timelimit**

If set limits the total time needed to complete the request and if it is reached the request is cancelled. If not set the browser's behavior is the only limiting factor. The value cannot be greater than the `LightFetchHttp.$ultimateTimeLimit`, which is by default 600 seconds, _if a greater value is set, it will act as if not limit is set_!

usage:
```Javascript
fetcher.set_timelimit(90); // Sets the timelimit to 90 seconds
```
The default is `null` - not set.

### **fillResponseHeaders**

It is `false` by default. When set to `true`, the response headers are included in the result data (see more details in the result description).

### **expectedContent**

Specifies what kind of content is expected in the response - i.e. how to process it into javascript result object. There are a small number of built-in (almost) trivial processing routines and a few BindKraft supplied processors for content often used with BindKraft. Additional and custom processors can be added by custom code by registering them in the `LightFetchHttp.$returnTypeProcessors` static map:

```Javascript
LightFetchHttp.$returnTypeProcessors[mycontent] = "MyContentHttpResponseProcessor";
```
This registers a processor for `mycontent` so that it can be used as a value for the `expectedContent` property. See [LightFetchHttp responses processors](LightFetchHttpResponses.md) for details on how to write one.


### **withCredentials**

### **queryBoolAsNumber**

### **queryMaxDepth**

### **postDataEncode**

Sets/gets the body encoder.

postDataEncode can be set to:

- string: name of built-in encoding (see the list below)

- callback: Delegate, function that receives the following args: fetcher, xhr, bodydata

where
fetcher is the instance of this class that calls it
xhr is the xmlHTTPRequest object in opened state
bodydata is the data passed in by the caller, it needs to be encoded and returned in the encoded form
returns the encoded data

The callback (and the built-in encoders) can and most often should set some headers (Content-type most notably). More details in the BK docs.

The available built-in encoders are:

`json`

> encodes the bodydata to JSON and sets the content-type to `application/json`
`raw`

>Pass through. The caller should set headers if necessary. The [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData), [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) and `string` do not need explicit header - the needed headers will be included by the browser. [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)s also set the correct content type if their type property contains one. Note that `URLSearchParams` is not supported by older browsers and still may have some quirks in some browsers. Use `form` encoding to send traditional `application/x-www-form-urlencoded` form data.
`form`

> Encodes the data using the traditional URL encoding and sets the content type to `application/x-www-form-urlencoded`.
`multipart`

> Encodes the data into FormData, leaves the browser to process it further and set headers as necessary. These headers will NOT be available through `getHeader` method.
For `form` and `multipart` the property `queryMaxDepth` is important. If it is 0 the encoded data will not be traversed beyond first level (e.g. sub-objects or arrays will not be encoded.). If it is greater than 0 that much levels will be traversed and their names in encoded data will look like `l0_name.l1_name.l2_name`. E.g. `{ a: { b: { c: 1 }}}` will encode (in URL encoding) as `a.b.c=1`. The same applies to `multipart`.


Custom encoder {preparedBody: body, bodyData: bodydata, requestData: reqdata} TODO: Complete the description.


### **url**

### **method**

## Methods

**addPlugin(plugin)**

**removePlugin(plugin_ot_type)**

**removeAllPlugins()**

**set_bearerTokens**

**url(v)**

**setHeader(header, content)**

**getHeader(header)**

**releaseActiveResult()**

**isOpened()**

**isComplete()**

**getAllResponseHeaders()**

**getResponse()**

**get(url, requestDAta, expectedType)**

**post(url, data, enctype, expectedType)**

**postEx(url, requestData, data, enctype, expectedType)**

**reset(expectedType)**

## Events

**finished**

**done**

**sent**

**progressed**



Loading