mavoweb / mavo Goto Github PK
View Code? Open in Web Editor NEWCreate web applications entirely by writing HTML and CSS!
Home Page: https://mavo.io
License: MIT License
Create web applications entirely by writing HTML and CSS!
Home Page: https://mavo.io
License: MIT License
To enable people to build contact forms and the like with wysie!
https://medium.com/@mariusc23/send-an-email-using-only-javascript-b53319616782
Structures like this should be allowed:
<a property="url" data-multiple>
<span property="name"></span>
</a>
and produce JSON like:
url: [
{ "url": "http://...", "name": "..." },
{ "url": "http://...", "name": "..." },
...
]
Currently if the order of properties in the template is different than the order in the JSON, the order in the JSON will change. Also, if there are any unhandled properties, they will be added at the end when saving.
Not sure if this should be considered a bug, since JSON objects are supposed to be unordered. However, it would mess up any diffing.
As discussed with @karger today.
Idea: Strings that happen to be the same as some id
property in the data structure can be dereferenced to the object that contains this property. In case of duplicate values, first (or last?) one wins.
Implementation thoughts:
id
so we don’t have to traverse the entire tree.Do not create editors for all properties when the outer scope is edited. Make everything editable, but actually create the editor when the user interacts with the property (1).
This way, editing of an entire collection will become much faster, as both DOM interaction and number of elements will be minimized.
(1) Property interaction =
For code
<ul data-store="...">
<li property="foo" data-multiple>...
</ul>
Special casing uls means add button is added after <ul>
instead of after <li>
therefore outside the [data-store]
They shouldn’t be deleted until save. Instead, just hide them and mark them for deletion upon save.
Currently the active Storage subclass for each wysie instance handles both (de)serialization and storage. These should be separate, so we could support multiple filetypes regardless of storage. E.g. so that a collection without child collections/scopes could be saved as a CSV, to take advantage of append-only permissions, such as the ones SOLID supports (append only is useless for JSON files).
Numbers need a lot of touchup to be presentable (rounding, thousand separators, ±Infinity to ±∞ to name a few), but that touchup should not affect the internal value that will be stored.
Currently, if a user adds wysie properties to an item that is going to be a collection, the item is removed from the DOM and used as a template. If it contains any data, it is used as default values and if its data actually need to be stored, it needs to be reentered.
This is disruptive and confusing.
The common flow is, I add an item with my data, I style it, then I wysify it. The item should still be there, just editable. I can always delete it if I don’t want it. Also, its data could become examples in the sense of using them in placeholders, but they should not become default values. Using them as default values forces people to meticulously clean up their template in order to make a usable application, which could be done automatically. If I want to specify default values, there should be a separate attribute for that. E.g. in the list of talks, if the first talk is in Singapore, I don't want to have to have to replace Singapore every time I add a new talk. Instead, it could be used in the placeholder, which instead of (city)
could become City, ex: Singapore
.
Implementation-wise:
data-default
attribute for default values. If used with no value, the content becomes the default value.<template>
tag. Maybe an attribute too?i.e. when editing. They do work when initially rendering.
Tested in Firefox 45b5.
A common UI pattern is having an item automatically added to a collection instead of having to press an "Add item" button. E.g. most to-do lists do this.
Wysie should do this for top-level collections. For nested collections, it would probably modify the layout way too much.
Caveat: Item needs to have some flag set so that it's not saved if the user has not interacted with it, since this is not the same as clicking "add item".
Autocomplete with values of the same property from other items of the collection.
Very weird stuff happens with the caret.
Verified that this is NOT a browser bug, but a wysie bug.
i.e. they should not be editable and should not be saved, without requiring a "computed" class.
The use case for not doing that is in case the author wanted an editable/saveable property with an expression as its default value. However, that's quite niche and can always be achieved by assigning the expression to the data-default
attribute.
Edit to make this current:
Currently, the only data edit that can be undone is deletion. That is special-cased, implemented via a rather clumsy mechanism that involves a lot of special casing in expressions etc, it’s buggy, increases the amount of stuff that needs to be styled, both by Mavo and by the author, and complicates the eventual data mutation API.
Instead, soft deletion should be abolished, and all data mutations should be added to an undo stack that can be undone and redone via shortcuts and potentially Mavo bar buttons.
This will also make it much easier to implement diff-based (incremental) saving by storage backends, if there is a record of what actions have happened since the last save.
Original text (which doesn’t make any sense now):
If #6 is implemented, then edit, save, cancel will become global (no need to edit items separately if the editing is just-in-time).
However, that makes it imperative to have a different mechanism for error recovery than a cancel button: Undo. If I can edit all my talks at once, I don't want to have to cancel ALL my edits because I made a mistake.
One can tab forwards but not backwards from a property that has a popup.
As discussed, to fix potential security hole.
Useful for collection items without a container, e.g.:
<dl>
<template data-multiple property=person>
<dt>name</dt>
<dd property=name></dd>
</template>
</dl>
Currently, pressing Save returns the user to read mode. However, since editing is now global, it makes sense that the user would want to save often, without necessarily concluding their editing. Therefore, Edit should become a toggle between edit and read mode, and save should do nothing more than save.
Then we can also move the saving progress indicator to the save button, and maybe in the future have autosave.
The only wart is, now what does cancel do?
The easiest to implement option would be that it just discards any unsaved changes. If they enabled autosave, well, tough luck. This is probably what we'll do initially. And rename it to "Revert", obvs.
As much as we're not focusing on legacy, this will be a killer feature for adoption.
As it currently stands, if somebody has a collection in HTML, they must still make a template and either convert their data to JSON manually, or enter them via the UI. This is a huge hassle, which for most cases could be avoided pretty easily.
If the storage file is empty, wysie would kickstart the import. Once the data is imported & saved, the user would get a message to clean up their HTML to avoid duplicate data being shown.
This is also a nice self-contained project for a UROP, though I'm not optimistic that it would be of interest.
If the nested editor contains a property (or is a property), it should not be removed from the DOM. Instead, it should just be hidden until edit mode.
This will enable variable options per select:
…
"foo": [
{
"bar": "optionK",
"barOption": ["option1", "option2", …, "optionN"]
}
…
]
…
<article property=foo data-multiple>
<span property="bar">
<select>
<option property=barOption></option>
</select>
</span>
</article>
Because it triggers blur
on the editor.
#3 would offer a potential fix, as hard line breaks could be stripped off before passed to textarea.value
.
If a <time>
's datetime
attribute is a duration, an appropriate editing widget needs to be used. Currently, it will incorrectly be a date input.
This would also make #2 easier.
Currently, the latter overwrites the former.
Instead, both should coexist and saved as an array. Then, in the future, the user can turn them into a collection with zero data loss.
It's basically the exact inverse of treating a singular scope as an array when rendering, if its property is a collection in the template.
Collections already allow for custom wysie buttons, i.e. buttons near the collection with a class of wysie-add
or add
. They should also have an attribute to specify where they will add an item, if that's not the collection closest to them. Being able to move items around with the press of a button will be immensely useful for a number of use cases, e.g. shopping carts, categorization tasks and many others.
Since <input>
can't wrap, it can cause really weird results when it's used to edit wrapped elements:
Potential solutions:
max-width
on <input>
equal to the available width on the first line. Probably the easiest one, but it breaks wysiwyg-ness a bit when you have two lines of text and they suddenly become a scrolled one on edit. OTOH, it's done a lot, so people are used to it.<inputs>
, simulate the wrapping logic and add/remove inputs as needed. Probably a huge mess.<textarea>
everywhere, instead of <input>
, as <textarea>
does wrap. Probably hard to make it emulate a wrapped inline element, as it's a block.contentEditable
. Always a mess.This is about the saved order of items, which is separate from any future end user sorting.
Many types of collections need this and are not necessarily ordered by any particular property, e.g. todo lists, palettes (lists of colors) etc.
To consider: Where to drag from? Should the entire item be draggable (might interfere with other bits of the UI given the huge variance of different wysies) or should there be a resize handle? If the latter, where to place said resize handle? (again, the variance of wysies makes any UI addition hard)
Depends on: #6
Once #6 is implemented, then edit, save, cancel will all become global, i.e. each will have one button per wysie instance.
As it currently stands, it's very difficult to add any UI to the user's template because of the huge variance between different wysies. The less we change their template, the better.
All global controls need to move to a bar at the top, which will be visible only when its corresponding wysie instance is visible.
List of global controls (assuming #6 is implemented):
Being separate will make styling much easier too, and can actually be a usability improvement in cases of large wysies that span longer than the viewport height, in which case one has to scroll up and down a lot to reach global controls or to see the progress indicator. It is also on par with what many CMSes do, e.g. Wordpress:
Challenges: What to do when there are more than 1 wysies visible on the screen?
This doesn't matter much to simple expressions, but it does to things like ${myCollection.length}
Use cases:
Possible solution: Use mutation observers to track changes to content with expressions. Since we have the old value, the new value and the expression value(s), we can figure out how to change the stored expression to include the change.
In addition to add, it may be efficient to duplicate/modify an existing item.
This would also be a way to address the "which template to use for multiple types" problem we discussed, though not a complete solution.
Case in point:
<a property="url">
<span property="name"></span>
</a>
Entire thing gets hidden when there is no URL.
✖makes it look like a close button, not a delete button.
Currently, it makes the following assumptions:
All these assumptions are false.
Possible structure:
There should be a permissions object (Wysie.Storage#can
?) whose properties would be:
and whose values would be either true or false. It would be possible to subscribe to permission changes and act accordingly every time there is a transition.
They should be editable too.
Multiline strings often need simple formatting, such as links, bold etc.
This is currently not possible, as everything is done through textContent
.
Currently properties that are not in a template are preserved, but:
E.g. when all properties are either exposed or computed/readonly, such as the colour picker example.
Enter should insert item below (except if there's a default handling, like in textareas etc)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.