Skip to content

Commit

Permalink
Merge pull request #133 from web-atoms/dev
Browse files Browse the repository at this point in the history
XF Improvements
  • Loading branch information
ackava committed Feb 27, 2020
2 parents 3c5100a + 24bc69a commit dd6fc6c
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 57 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Expand Up @@ -12,12 +12,12 @@
"url": "http://http://192.168.0.187:8080/",
"webRoot": "${workspaceFolder}/",
},

{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/src/test.ts",
"program": "${workspaceFolder}/node_modules/@web-atoms/unit-test/index.js",
"args": ["./dist/tests"],
"cwd": "${workspaceFolder}",
"protocol": "inspector",
"outFiles": [
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@web-atoms/core",
"version": "1.1.90",
"version": "1.1.105",
"description": "Web Atoms Core",
"main": "index.js",
"scripts": {
Expand Down
6 changes: 3 additions & 3 deletions src/core/AtomBridge.ts
Expand Up @@ -26,8 +26,8 @@ export abstract class BaseElementBridge<T extends IAtomElement> {
type: string
| ((n: any, ... nodes: XNode[]) => XNode)
| (new (... a: any[]) => any),
node: any,
app: any): T;
node?: any,
app?: any): T;

public abstract attachControl(element: T, control: IUIAtomControl): void;

Expand Down Expand Up @@ -424,7 +424,7 @@ declare var window, global;
const globalNS = (typeof window !== "undefined" ? window : (global as any)) as any;
globalNS.AtomBridge = AtomBridge;

if (window) {
if (typeof window !== "undefined") {
AtomBridge.instance = new AtomElementBridge();
AtomBridge.platform = "web";
}
6 changes: 5 additions & 1 deletion src/core/Bind.ts
Expand Up @@ -112,7 +112,11 @@ export default class Bind {
public static twoWays<T extends IAtomComponent = IAtomComponent>(
sourcePath: bindingFunction<T>,
events?: string[]): Bind {
return new Bind(twoWays, sourcePath, null, events);
const b = new Bind(twoWays, sourcePath, null, events);
if (!(b.thisPathList || b.pathList)) {
throw new Error(`Failed to setup twoWay binding on ${sourcePath}`);
}
return b;
}

public readonly sourcePath: bindingFunction;
Expand Down
41 changes: 25 additions & 16 deletions src/core/ExpressionParser.ts
Expand Up @@ -7,7 +7,7 @@ export function parsePath(f: any, parseThis?: boolean): PathList[] {

str = str.split("\n").filter((s) => !/^\/\//.test(s.trim())).join("\n");

const key: string = (parseThis === undefined ? "un:" : parseThis ) + str;
const key: string = (parseThis === undefined ? "un:" : (parseThis ? "_this:" : "_noThis:") ) + str;

const px1: PathList[] = viewModelParseWatchCache[key];
if (px1) {
Expand Down Expand Up @@ -37,7 +37,16 @@ export function parsePath(f: any, parseThis?: boolean): PathList[] {

const isThis: boolean = parseThis === undefined ? (index === 0 || parseThis) : parseThis;

const p: string = (isThis ? "\\_this|this" : (str.substr(0, index) || "x")).trim();
const p: string = (isThis ? "\\_this|this" : (str.substr(0, index) || "")).trim();

/**
* This is the case when there is no parameter to check and there `parseThis` is false
*/
if (p.length === 0) {
const empty = [];
viewModelParseWatchCache[key] = empty;
return empty;
}

str = str.substr(index + 1);

Expand Down Expand Up @@ -116,32 +125,32 @@ interface IPathLists {

const viewModelParseWatchCache2: {[key: string]: IPathLists } = {};

export function parsePathLists(f: any, parseThis?: boolean): IPathLists {
export function parsePathLists(f: any): IPathLists {

let str: string = f.toString().trim();
const str = f.toString().trim();

const key: string = (parseThis === undefined ? "un:" : parseThis) + str;
const key: string = str;

const px1 = viewModelParseWatchCache2[key];
if (px1) {
return px1;
}

str = str.split("\n").filter((s) => !/^\/\//.test(s.trim())).join("\n");
// str = str.split("\n").filter((s) => !/^\/\//.test(s.trim())).join("\n");

if (str.endsWith("}")) {
str = str.substr(0, str.length - 1);
}
// if (str.endsWith("}")) {
// str = str.substr(0, str.length - 1);
// }

if (str.startsWith("function (")) {
str = str.substr("function (".length);
}
// if (str.startsWith("function (")) {
// str = str.substr("function (".length);
// }

if (str.startsWith("function(")) {
str = str.substr("function(".length);
}
// if (str.startsWith("function(")) {
// str = str.substr("function(".length);
// }

str = str.trim();
// str = str.trim();

const pl = {
pathList: parsePath(str, false),
Expand Down
60 changes: 31 additions & 29 deletions src/core/XNode.ts
Expand Up @@ -96,55 +96,57 @@ export default class XNode {
} as any;
}

public static attached<T>(): AttachedNode {
/**
* This is only for intellisense...
*/
public static attached(): AttachedNode {
return {
factory: true,
attached: true
} as any;
}

public static property(): NodeFactory {
return {
factory: true
} as any;
}

/**
* Declares Root Namespace and Assembly. You can use return function to
* to declare the type
* @param ns Root Namespace
*/
public static namespace(ns: string, assemblyName: string) {
return (type: any) => {
return (type: string, isTemplate?: boolean) => {
return (c) => {
for (const key in type) {
if (type.hasOwnProperty(key)) {
const element = type[key];
for (const key in c) {
if (c.hasOwnProperty(key)) {
const element = c[key];
if (element) {
const n = ns + "." + type + ":" + key + ";" + assemblyName;
if (element.factory) {
type[key] = {
factory(a?: any, ... nodes: XNode[]) {
return new XNode(n, a, nodes, true, element.isTemplate);
},
toString() {
return n;
}
};
} else if (element.attached) {
type[key] = (a) => {
const r = {
[n]: a
};
Object.defineProperty(r, "toString", {
value: () => n,
enumerable: false,
configurable: false
});
return r;
const af: any = (a) => {
const r = {
[n]: a
};
}
Object.defineProperty(r, "toString", {
value: () => n,
enumerable: false,
configurable: false
});
return r;
};
af.factory = (a?: any, ... nodes: any[]) =>
new XNode(n, a, nodes, true, element.isTemplate );
af.toString = () => n;
c[key] = af;
}
}
}
const tn = ns + "." + type + ";" + assemblyName;
c.factory = (a?: any, ... nodes: XNode[]) => {
return new XNode(type, a, nodes);
return new XNode(tn, a, nodes, false, isTemplate);
};
c.toString = () => type;
c.toString = () => tn;
};
};
}
Expand Down
11 changes: 10 additions & 1 deletion src/tests/core/ExpressionParserTest.ts
@@ -1,6 +1,6 @@
import Assert from "@web-atoms/unit-test/dist/Assert";
import Test from "@web-atoms/unit-test/dist/Test";
import { parsePath } from "../../core/ExpressionParser";
import { parsePath, parsePathLists } from "../../core/ExpressionParser";
import { AtomTest } from "../../unit/AtomTest";

export class ExpressionParserTest extends AtomTest {
Expand Down Expand Up @@ -77,4 +77,13 @@ export class ExpressionParserTest extends AtomTest {
Assert.equals(1, p.length);
}

@Test
public parseLongPath(): void {
const p = parsePathLists(`function () {
return _this.viewModel.comboBox.searchText;
}`);

Assert.equals(1, p.thisPath.length);
}

}
22 changes: 21 additions & 1 deletion src/tests/jsx/JSXTest.ts
@@ -1,7 +1,27 @@
import Assert from "@web-atoms/unit-test/dist/Assert";
import Test from "@web-atoms/unit-test/dist/Test";
import XNode, { RootObject } from "../../core/XNode";
import { AtomTest } from "../../unit/AtomTest";

const ns = XNode.namespace("A", "B");
@ns("C")
class C extends RootObject {

public static p = XNode.property();

public static n = XNode.attached();

}

export default class JSXTest extends AtomTest {


@Test
public propertyTest() {
const x = (C.p as any).factory();
Assert.equals("A.C:p;B", x.name);

const g = C.n(1);
Assert.equals(g["A.C:n;B"], 1);
}

}
4 changes: 2 additions & 2 deletions src/xf/XFApp.ts
Expand Up @@ -27,8 +27,8 @@ export default class XFApp extends A.App {
this.put(NavigationService, this.resolve(XFNavigationService));
this.put(BusyIndicatorService, this.resolve(XFBusyIndicatorService));

const s = bridge.subscribe((m) => {
this.broadcast(m.channel, m.data);
const s = bridge.subscribe((channel, data) => {
this.broadcast(channel, data);
});

// register for messaging...
Expand Down
4 changes: 4 additions & 0 deletions src/xf/controls/AtomXFControl.ts
Expand Up @@ -41,6 +41,10 @@ export class AtomXFControl extends AtomComponent<IAtomElement, AtomXFControl> {
return (AtomBridge.instance as any).getStaticResource(this.element, name);
}

public loadXaml(text: string) {
(AtomBridge.instance as any).loadXaml(this.element, text);
}

protected setElementValue(element: any, name: string, value: any): void {
if (/^event/.test(name)) {
this.bindEvent(element, name.substr(5), async () => {
Expand Down

0 comments on commit dd6fc6c

Please sign in to comment.