Skip to content

Commit df69022

Browse files
committed
merge master into app-loading
2 parents 984db81 + 3e5c0fa commit df69022

File tree

12 files changed

+446
-28
lines changed

12 files changed

+446
-28
lines changed

css/ide.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ body { justify-content: stretch; }
8989
.main-pane .notices > .notice > .time { margin-right: 10px; }
9090

9191
.main-pane .notices > .notice.error { background: rgb(255, 216, 222); }
92+
.main-pane .notices > .notice.warning { background: rgb(255, 247, 217); }
9293

9394
/****************************************************************************\
9495
* Editor

examples/CRM.eve

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ bind @browser
248248
[#h2 text: "Learn more about Eve"]
249249
[#ul children:
250250
[#li children: [#a href: "http://witheve.com" text: "Homepage"]]
251-
[#li children: [#a href: "https://witheve.github.io/docs/guides/quickstart/" text: "Quick Start Tutorial"]]
251+
[#li children: [#a href: "https://witheve.github.io/docs/tutorials/quickstart/" text: "Quick Start Tutorial"]]
252252
[#li children: [#a href: "http://github.com/witheve" text: "GitHub Repository"]]]
253253
[#h2 text: "Join the Community"]
254254
[#ul children:

src/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ export class EveClient {
224224
}
225225

226226
onClose() {
227-
227+
this.ide.injectNotice("warning", "The editor has lost connection to the Eve server. All changes will be made locally.");
228228
}
229229

230230
onMessage(event) {

src/ide.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,9 +2021,10 @@ export class IDE {
20212021
let items = [];
20222022
for(let notice of this.notices) {
20232023
let time = new Date(notice.time);
2024-
2024+
let formattedMinutes = time.getMinutes() >= 10 ? time.getMinutes() : `0${time.getMinutes()}`;
2025+
let formattedSeconds = time.getSeconds() >= 10 ? time.getMinutes() : `0${time.getSeconds()}`;
20252026
items.push({c: `notice ${notice.type} flex-row`, children: [
2026-
{c: "time", text: `${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`},
2027+
{c: "time", text: `${time.getHours()}:${formattedMinutes}:${formattedSeconds}`},
20272028
{c: "message", text: notice.message}
20282029
]});
20292030
}

src/renderer.ts

Lines changed: 226 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,216 @@ export var activeIds = {};
4141
export var activeElements:{[id : string]: RecordElement|null, root: RecordElement} = {"root": document.createElement("div")};
4242
activeElements.root.className = "program";
4343

44-
var supportedTags = {
45-
"div": true, "span": true, "input": true, "ul": true, "li": true, "label": true, "button": true, "header": true, "footer": true, "a": true, "strong": true,
46-
"h1": true, "h2": true, "h3": true, "h4": true, "h5": true, "h6": true,
47-
"ol": true, "p": true, "pre": true, "em": true, "img": true, "canvas": true, "script": true, "style": true, "video": true,
48-
"table": true, "tbody": true, "thead": true, "tr": true, "th": true, "td": true,
49-
"form": true, "optgroup": true, "option": true, "select": true, "textarea": true,
50-
"title": true, "meta": true, "link": true,
51-
"svg": true, "circle": true, "line": true, "rect": true, "polygon":true, "text": true, "image": true, "defs": true, "pattern": true, "linearGradient": true, "g": true, "path": true
52-
};
53-
var svgs = {"svg": true, "circle": true, "line": true, "rect": true, "polygon":true, "text": true, "image": true, "defs": true, "pattern": true, "linearGradient": true, "g": true, "path": true};
54-
// Map of input entities to a queue of their values which originated from the client and have not been received from the server yet.
44+
// Obtained from http://w3c.github.io/html-reference/elements.html
45+
var supportedTagsArr = [
46+
"a",
47+
"abbr",
48+
"address",
49+
"area",
50+
"article",
51+
"aside",
52+
"audio",
53+
"b",
54+
"base",
55+
"bdi",
56+
"bdo",
57+
"blockquote",
58+
"body",
59+
"br",
60+
"button",
61+
"canvas",
62+
"caption",
63+
"cite",
64+
"code",
65+
"col",
66+
"colgroup",
67+
"command",
68+
"datalist",
69+
"dd",
70+
"del",
71+
"details",
72+
"dfn",
73+
"div",
74+
"dl",
75+
"dt",
76+
"em",
77+
"embed",
78+
"fieldset",
79+
"figcaption",
80+
"figure",
81+
"footer",
82+
"form",
83+
"h1",
84+
"h2",
85+
"h3",
86+
"h4",
87+
"h5",
88+
"h6",
89+
"head",
90+
"header",
91+
"hgroup",
92+
"hr",
93+
"html",
94+
"i",
95+
"iframe",
96+
"img",
97+
"input",
98+
"ins",
99+
"kbd",
100+
"keygen",
101+
"label",
102+
"legend",
103+
"li",
104+
"link",
105+
"map",
106+
"mark",
107+
"menu",
108+
"meta",
109+
"meter",
110+
"nav",
111+
"noscript",
112+
"object",
113+
"ol",
114+
"optgroup",
115+
"option",
116+
"output",
117+
"p",
118+
"param",
119+
"pre",
120+
"progress",
121+
"q",
122+
"rp",
123+
"rt",
124+
"ruby",
125+
"s",
126+
"samp",
127+
"script",
128+
"section",
129+
"select",
130+
"small",
131+
"source",
132+
"span",
133+
"strong",
134+
"style",
135+
"sub",
136+
"summary",
137+
"sup",
138+
"table",
139+
"tbody",
140+
"td",
141+
"textarea",
142+
"tfoot",
143+
"th",
144+
"thead",
145+
"time",
146+
"title",
147+
"tr",
148+
"track",
149+
"u",
150+
"ul",
151+
"var",
152+
"video",
153+
"wbr"
154+
];
155+
156+
// Obtained from https://www.w3.org/TR/SVG/eltindex.html
157+
var svgsArr = [
158+
"a",
159+
"altGlyph",
160+
"altGlyphDef",
161+
"altGlyphItem",
162+
"animate",
163+
"animateColor",
164+
"animateMotion",
165+
"animateTransform",
166+
"circle",
167+
"clipPath",
168+
"color-profile",
169+
"cursor",
170+
"defs",
171+
"desc",
172+
"ellipse",
173+
"feBlend",
174+
"feColorMatrix",
175+
"feComponentTransfer",
176+
"feComposite",
177+
"feConvolveMatrix",
178+
"feDiffuseLighting",
179+
"feDisplacementMap",
180+
"feDistantLight",
181+
"feFlood",
182+
"feFuncA",
183+
"feFuncB",
184+
"feFuncG",
185+
"feFuncR",
186+
"feGaussianBlur",
187+
"feImage",
188+
"feMerge",
189+
"feMergeNode",
190+
"feMorphology",
191+
"feOffset",
192+
"fePointLight",
193+
"feSpecularLighting",
194+
"feSpotLight",
195+
"feTile",
196+
"feTurbulence",
197+
"filter",
198+
"font",
199+
"font-face",
200+
"font-face-format",
201+
"font-face-name",
202+
"font-face-src",
203+
"font-face-uri",
204+
"foreignObject",
205+
"g",
206+
"glyph",
207+
"glyphRef",
208+
"hkern",
209+
"image",
210+
"line",
211+
"linearGradient",
212+
"marker",
213+
"mask",
214+
"metadata",
215+
"missing-glyph",
216+
"mpath",
217+
"path",
218+
"pattern",
219+
"polygon",
220+
"polyline",
221+
"radialGradient",
222+
"rect",
223+
"script",
224+
"set",
225+
"stop",
226+
"style",
227+
"svg",
228+
"switch",
229+
"symbol",
230+
"text",
231+
"textPath",
232+
"title",
233+
"tref",
234+
"tspan",
235+
"use",
236+
"view",
237+
"vkern"
238+
];
239+
240+
supportedTagsArr.push.apply(supportedTagsArr, svgsArr);
241+
242+
function toKeys(arr) {
243+
var obj = {};
244+
for (var el of arr) {
245+
obj[el] = true;
246+
}
247+
return obj
248+
}
55249

250+
var supportedTags = toKeys(supportedTagsArr);
251+
var svgs = toKeys(svgsArr);
252+
253+
// Map of input entities to a queue of their values which originated from the client and have not been received from the server yet.
56254
var lastFocusPath:string[]|null = null;
57255
var selectableTypes = {"": true, undefined: true, text: true, search: true, password: true, tel: true, url: true};
58256

@@ -127,7 +325,14 @@ export function renderRecords() {
127325
}
128326
elem.entity = entityId;
129327
activeElements[entityId] = elem;
130-
elem.sort = entity.sort || entity["eve-auto-index"] || "";
328+
if(entity.sort && entity.sort.length > 1) console.error("Unable to set 'sort' multiple times on entity", entity, entity.sort);
329+
if(entity.sort !== undefined && entity.sort[0] !== undefined) {
330+
elem.sort = entity.sort[0];
331+
} else if(entity["eve-auto-index"] !== undefined && entity["eve-auto-index"][0] !== undefined) {
332+
elem.sort = entity["eve-auto-index"][0];
333+
} else {
334+
elem.sort = "";
335+
}
131336
if(parent) insertSorted(parent, elem)
132337

133338

@@ -140,7 +345,13 @@ export function renderRecords() {
140345
elem.entity = entityId;
141346
activeElements[entityId] = elem;
142347
if(entity.sort && entity.sort.length > 1) console.error("Unable to set 'sort' multiple times on entity", entity, entity.sort);
143-
elem.sort = (entity.sort && entity.sort[0]) || (entity["eve-auto-index"] && entity["eve-auto-index"][0]) || "";
348+
if(entity.sort !== undefined && entity.sort[0] !== undefined) {
349+
elem.sort = entity.sort[0];
350+
} else if(entity["eve-auto-index"] !== undefined && entity["eve-auto-index"][0] !== undefined) {
351+
elem.sort = entity["eve-auto-index"][0];
352+
} else {
353+
elem.sort = "";
354+
}
144355
let parent = activeElements[activeChildren[entityId] || "root"];
145356
if(parent) insertSorted(parent, elem);
146357
}
@@ -204,7 +415,7 @@ export function renderRecords() {
204415
} else if(value.length > 1) {
205416
console.error("Unable to set 'value' multiple times on entity", entity, JSON.stringify(value));
206417
} else {
207-
input.value = value[0]; // @FIXME: Should this really be setAttribute?
418+
input.setAttribute('value', value[0]);
208419
}
209420

210421
} else if(attribute === "checked") {
@@ -527,3 +738,4 @@ function injectProgram(node, elem) {
527738
export function renderEve() {
528739
renderer.render([{c: "application-container", postRender: injectProgram}]);
529740
}
741+

src/runtime/databases/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {Evaluation, Database} from "../runtime"
1111

1212
class TimeAgent {
1313

14-
static attributeOrdering = ["year", "month", "day", "hours", "hours-24", "ampm", "minutes", "time-string", "seconds", "frames"];
14+
static attributeOrdering = ["year", "month", "day", "hours", "hours-24", "ampm", "minutes", "time-string", "seconds", "timestamp", "frames"];
1515
static updateIntervals = {
1616
"year": 1000 * 60 * 60,
1717
"month": 1000 * 60 * 60,

src/runtime/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,9 +1414,9 @@ export function parseDoc(doc, docId = `doc|${docIx++}`) {
14141414
let parsedBlocks = [];
14151415
let allErrors = [];
14161416
for(let block of blocks) {
1417+
extraInfo[block.id] = {info: block.info};
14171418
if(block.info !== "" && block.info.indexOf("eve") === -1) continue;
14181419
let {results, lex, errors} = parseBlock(block.literal, block.id, block.startOffset, spans, extraInfo);
1419-
extraInfo[block.id] = {info: block.info};
14201420
// if this block is disabled, we want the parsed spans and such, but we don't want
14211421
// the block to be in the set sent to the builder
14221422
if(block.info.indexOf("disabled") > -1) {

src/runtime/server.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ function IDEMessageHandler(client:SocketRuntimeClient, message) {
189189
if(content) path = eveSource.getRelativePath(config.path, workspace);
190190
}
191191

192-
193192
if(!content && config.internal) {
194193
content = eveSource.get("quickstart.eve", "examples");
195194
if(content) path = eveSource.getRelativePath("quickstart.eve", "examples");

src/runtime/util/eavs.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
import {Changes} from "../changes";
66
import {TripleIndex} from "../indexes";
77

8+
const JSON_NULL_ID = "external|json|null";
9+
810
//---------------------------------------------------------------------
911
// JS conversion
1012
//---------------------------------------------------------------------
1113

1214
export function fromJS(changes: Changes, json: any, node: string, scope: string, idPrefix: string = "js") {
15+
if(json === null || json === undefined) return JSON_NULL_ID;
1316
if(json.constructor === Array) {
1417
let arrayId = `${idPrefix}|array`;
1518
changes.store(scope, arrayId, "tag", "array", node);
@@ -26,10 +29,15 @@ export function fromJS(changes: Changes, json: any, node: string, scope: string,
2629
let objectId = `${idPrefix}|object`;
2730
for(let key of Object.keys(json)) {
2831
let value = json[key];
29-
if(value.constructor === Array || typeof value === "object") {
30-
value = fromJS(changes, value, node, scope, `${objectId}|${key}`);
32+
if(value === null || value === undefined) {
33+
changes.store(scope, JSON_NULL_ID, "tag", "json-null", node);
34+
changes.store(scope, objectId, key, JSON_NULL_ID, node);
35+
} else {
36+
if(value.constructor === Array || typeof value === "object") {
37+
value = fromJS(changes, value, node, scope, `${objectId}|${key}`);
38+
}
39+
changes.store(scope, objectId, key, value, node);
3140
}
32-
changes.store(scope, objectId, key, value, node);
3341
}
3442
return objectId;
3543
} else {
@@ -39,6 +47,7 @@ export function fromJS(changes: Changes, json: any, node: string, scope: string,
3947

4048
export function toJS(index: TripleIndex, recordId) {
4149
let result;
50+
if(recordId === JSON_NULL_ID) return null;
4251
let isArray = index.lookup(recordId, "tag", "array");
4352
if(isArray !== undefined) {
4453
result = [];

test/eavs.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@ test("converting nested js objects and arrays", (assert) => {
4848
}, assert);
4949
assert.end();
5050
})
51+
52+
test("converting with null roundtrips", (assert) => {
53+
convert({
54+
beep: null,
55+
foo: [1, null, 2]
56+
}, assert);
57+
assert.end();
58+
})

0 commit comments

Comments
 (0)