Skip to content

Releases: mavoweb/mavo

v0.3.2

28 Jun 21:26
e9ff53c
Compare
Choose a tag to compare

This is a minor update with fixes for some bugs and regressions.

What's Changed

  • Unsupported events that backend services might send are ignored and don't break anything
  • Live storage attributes don't break the autosave anymore
  • Mavo now correctly interprets boolean data when loading it to the properties without the explicit datatype="boolean"

v0.3.1 Hotfix

28 Jun 21:25
3fa548f
Compare
Choose a tag to compare

What's Changed

We removed polyfill.io, a third-party service that has been recently compromised to serve malware. For more details, see: https://dev.to/snyk/polyfill-supply-chain-attack-embeds-malware-in-javascript-cdn-assets-55d6.

If you are unable to upgrade to v0.3.1, the good news is that Mavo only used this service for features that are currently supported everywhere, and any requests to it were gated behind our own local feature testing, so the impact should be minimal.

v0.3.0

27 Oct 18:57
Compare
Choose a tag to compare

We have some very exciting plans for Mavo going forwards, but the first step was to make a new, long overdue, release.

Breaking changes

  • A new way to define collections (mv-list/mv-list-item). You can use both to define a collection or mv-item-list or mv-list on their own, and the other one will be auto-added for you. mv-multiple is now deprecated but still works fine and just gets rewritten to mv-list/mv-list-item markup, so this is only a breaking change because you may have CSS that depends on the previous markup structure (e.g. child selectors).
  • The previously deprecated mv-like attribute has now been removed.
  • Property queries in get() (i.e. get(object, "key=value")) are not supported anymore. Use where or filter() for this.
  • The Dropbox backend is moved to a separate plugin to make Mavo lighter. Use mv-plugins="dropbox" anywhere to re-add support.
  • The CTRL/CMD + Backspace shortcut to delete a list entry is not supported anymore.
  • url() now does case insensitive matching by default—you can opt in to case sensitive matching via case_sensitive: true.

New Features

  • 🆕 mv-options attribute: limit properties to predefined options without having to create a <select>
  • 🆕 mv-item-bar attribute to customize list item controls (remove controls, add custom ones).
  • 🆕 mv-edit-as attribute: Teach Mavo how to edit new elements, e.g. web components.
  • 🆕 mv-attr-* family of attributes—a way for attributes to contain expressions without triggering browser errors or false loading.
  • You can now specify a plugin version in mv-plugins.
  • GitHub backend improvements:
    • When performing raw API calls, there is now a way to fetch more than one page, by adding a max_pages parameter.
    • When saving to a repo that doesn't yet exist, it is now possible to create a private repo (via the private storage attribute).
  • Local storage backend: 🆕 mv-storage-key attribute to override the localStorage key used.
  • You can now use mv-mode="edit" on mv-value elements to make dynamic collections editable.

MavoScript Changes

New functions

  • intersection()—to get a list of items that two lists have in common.
  • readable_datetime()—to get a date or date/time value as human-readable text (e.g., 13 Jun 1986 16:45).
  • pluralize()—to get the correct plural form of a word corresponding to the given number.
  • sort()—for locale-aware sorting of lists.
  • datetime()—Combine a date and (optionally) a time into a single date/time value in ISO format (e.g., 1986-06-13T16:45) that can be used as input for other date/time functions.
  • map()—Get properties from list items.

Function improvements

  • get() can accept multiple keys, e.g., get(group("foo": group("bar": "baz")), "foo", "bar") will return baz.
  • duration() now allows units to be specified explicitly, e.g., duration(ms, "days"). Negative inputs to duration() now produce negative time outputs.
  • url() now supports options to control case sensitivity, what is matched, what URL is used, and whether multiple results are returned.
  • Functions with 2-word names—groupby(), fromlast(), and tofirst()—renamed to group_by(), from_last(), and to_first() respectively to be consistent with other functions and better readability. Old functions still work but are deprecated and will be removed in the next release.

Special property improvements

  • $all.$previous/$all.$next to get all collection items before/after the current one.

Bugfixes and other improvements

  • Order of relative button ids in the mv-bar attribute is now preserved.
  • When changing the storage location of a Mavo app via the URL (e.g. via a ?myapp-storage=... URL), app id is now case insensitive.
  • Expressions now work properly with on* attributes.
  • The boolean disabled attribute works correctly with expressions on all supported elements, including <optgroup>, <option>, and <fieldset>.
  • And 130 more bugfixes and smaller improvements!

Plugins

New plugins

  • 🆕 List Separator plugin—Store and read lists of simple properties as a single text value. Useful in conjunction with the Google Sheets plugin to store multiple values in a single cell.
  • 🆕 Share plugin—Share data via system clipboard, email, contacts or messaging applications, and Bluetooth or Wi-Fi channels.
  • 🆕 Google Calendar Backend plugin—Integrate Google calendars into your Mavo apps.
  • 🆕 Autoload plugin—Let Mavo load all the needed plugins for you automatically.
  • 🆕 Spanish Locale plugin—Translates all Mavo UI to Spanish.

Notable improvements to existing plugins

  • TinyMCE: Added a CMD/CTRL + E shortcut to mark up code blocks.

For developers of custom backends

  • Mavo#load() now accepts a data parameter for overriding the data loaded.
  • New Mavo#push() for backend pushes.
  • New mv-remotedatachange event on Mavo.Backend to signify that data changed remotely.

New Contributors

v0.2.4

01 Jul 13:47
Compare
Choose a tag to compare

This is a relatively small release that fixes a few bugs and regressions. There are however a few new features and potentially breaking changes, detailed below.

Breaking changes

  • mv-edit and mv-edit-* attributes have been renamed to mv-editor and mv-editor-*. Mavo does try to rewrite existing markup to minimize breakage during the transition whenever possible. Going forwards, mv-edit and mv-edit-* will be used for attributes that control how editing works (starting with mv-edit-type below)
  • When an object is displayed on a simple property, instead of Mavo trying to find a suitable property to use, the value of the property is now the entire object (#692)
  • mv-like still works, but is deprecated and will be removed in the next release.

New features

  • You can now control whether a property is edited via a popup or inline with the mv-edit-type attribute! (#695)
  • The mv-editor property is now "live", i.e. expressions work in it.
  • mv-storage-query (and mv-source-query/mv-init-query) attribute now can be used to make a GraphQL query when using the Github backend

v0.2.3

04 Feb 16:09
Compare
Choose a tag to compare

We noticed some nasty regressions that v0.2.2 introduced so we are releasing a new version shortly after.

You should avoid v0.2.2 and go straight to v0.2.3 especially in apps that:

  • Include lists of simple properties, with mv-mode="edit" applied
  • Include radio buttons that are Mavo properties

In addition, this new version includes an experimental new feature, intended for JS developers, plugin authors, or otherwise advanced users: Asynchronous data (i.e. promises) are now supported, both in loaded data, as well as expressions. This opens the door for many kinds of expressions that were not previously possible, and allows us to introduce more powerful functions in the future.

v0.2.2

01 Feb 19:16
Compare
Choose a tag to compare

This is not a huge release, but there are some breaking changes. Make sure to review before upgrading!
Note that anyone using get.mavo.io/stable/ or get.mavo.io/0.2/ will be automatically upgraded to this release. You can rollback to v0.2.1 by using get.mavo.io/0.2.1/ instead.

Breaking changes

  • JS syntax is not allowed in Mavo expressions anymore. This opens the way for many future improvements to how expressions are handled. Note that if you're using custom JS functions in your expressions, those will continue to work fine, since function calls are perfectly valid MavoScript. One example of something you may need to convert: if you were using {} to define key-value pairs in your expressions, you will now need to use group() instead.
  • This version drops support for IE11, Chrome 41, Microsoft Edge < 16 as their market share is fairly low at this point
  • The code that allowed people to send "edit suggestions" as Github pull requests has now been moved to a plugin: https://plugins.mavo.io/plugin/github-pr . Use mv-plugins="github-pr" on any apps of yours that depend on this functionality.

Other changes

  • duration() now accepts a second parameter for number of terms returned (e.g. "2 hours, 30 minutes").
  • duration() is now multi-valued, i.e. if used with a list of values, it will return a list of durations.
  • Github backend now works correctly when the default branch is main if no branch is specified. It will continue to work correctly for repos where the default branch is still master, but that will cost an extra HTTP request.
  • indeterminate is now correctly supported as a boolean attribute. This allows you to easily do checkboxes that follow the select/unselect all pattern a highly recommended UI enhancement for collections that contain checkboxes.
  • 12 bugfixes
  • Several more code improvements

For plugin authors and JS developers

  • For developers of custom backends: Authors can now pass arbitrary data to your backend via attributes. E.g. mv-storage-foo="1" will be converted to {foo: "1"} and passed to your backend as a second constructor argument. See how the awesome new Google Sheets plugin uses this for additional metadata like sheet and range. These attributes are "live" as well, and could contain expressions, opening up so many creative possibilities!
  • A new hook allows you to use JS to easily transform data before it's rendered (read more)
  • A new save-start hook allows you to intercept saving
  • There is now a Mavo#destroy() method

Additional credits:

  • @DmitrySharabin for his huge help with this release, both in terms of code, as well as issue triaging, assisting with debugging etc.
  • @parulsingh23 for the duration() enhancements

v0.2.1

28 May 21:04
Compare
Choose a tag to compare

A rather small release.

  • One can now specify a separate backend for uploads, via the mv-uploads attribute
  • condense() function to remove empty values from a list. Basically a more readable shortcut to the first(count(list), list) hack.
  • New precision argument to time(), defaulting to "seconds"
  • <pre> is added to block elements
  • 13 bugfixes

v0.2.0

26 Jun 22:57
Compare
Choose a tag to compare

It's been almost a year and a half since our last release, so this one is pretty huge. We'll try to summarize the changes the 330 (!) commits this release introduced below, but this list is far from comprehensive.

We strongly recommend that everyone upgrades to this version of Mavo, anything before that is fairly outdated at this point. We will not provide support for older versions, unless you discover a regression (i.e. something that was working in the old version that isn't working in the new one)

Backwards incompatible changes

  • The URL structure to use our CDN has slightly changed to be more consistent and predictable. If you were using e.g. https://get.mavo.io/mavo.js to link to the latest stable version, you should now use https://get.mavo.io/stable/mavo.js. The https://get.mavo.io/mavo.js URL will now link to the latest development version (i.e. it is the same as the old dev.mavo.io/dist/mavo.js which still works as well). If this seems confusing, just visit mavo.io/get, answer the questions again and copy the provided URLs! You don't need to change anything if you're linking to a specific version, or to the latest dev version.
  • Date formatting is now done via an extra parameter on date functions (see "Date-based expressions" below)
  • mv-autosave without a value now defaults to 0 seconds (instant) instead of 3 seconds. However, we strongly recommend using it with a non-zero value for backends that generate an edit history (such as Github or Dropbox), otherwise you will end up with a huge, useless history.
  • The previously deprecated mv-optional attribute is now removed. Use mv-initial-items="0" instead
  • Microdata attributes (itemprop, itemscope, itemtype) are no longer supported for specifying Mavo properties. Mavo will still look in itemprop for a property name, if the property attribute is used without a value. The primary reason for this was that a) our research indicated that this syntax was very rarely used for specifying Mavo properties and b) People were often using Microdata in conjunction with Mavo, without expecting Mavo to do anything with these attributes, and then did not understand why this changed the way their apps were working.
  • The previously deprecated yes-* syntax in mv-bar has now been removed. Please use the new syntax only.

Mavo Actions

Probably the biggest major new feature is Mavo Actions. They allow you to create your own controls that modify the data in custom ways when activated, and they can be quite powerful. You can read all about them in the documentation.

These actions are sufficiently novel, that we published a peer-reviewed research paper about them at a top-tier Human-Computer Interaction conference (UIST). If it's your cup of tea, you can read the paper here.

Note that Mavo's own data manipulation controls (buttons for deleting items, adding new items etc) are now implemented with Actions as well!

Date-based expressions

  • Date formatting is now done via a second parameter in each date component function, not via the weird .formatType syntax we had before. E.g. instead of month(date).name you would write month(date, 'name') and instead of digits(2, month(date)), you would write month(date, '00'). For details, you can look at the documentation for these functions.
  • All date component functions (e.g. day() and days()) now return the number of milliseconds for that date component when called with no parameters, so you can do more readable comparisons of date intervals, (e.g. day() and days() both return 86400000). So something like birthday - $today > 6 * 86400000 can now be more readably written asbirthday - $today > 6 * days().
  • New duration() function for displaying time intervals in a readable way, based on a number of milliseconds (which is what subtracting dates returns in Mavo). E.g. duration(10000) will print out "10 seconds", duration(1000000) will print out "16 minutes" and duration(100000000) will print out "1 day".
  • Date formatting functions (as well as the new duration()) are localized based on the language of the Mavo app and not just that of the document root.

Uploads

  • jsdelivr now used instead of rawgit.com for serving images uploaded to Github (if Github Pages is disabled), since rawgit is officially dead.
  • Uploads are now allowed on <a> and <link> elements with an mv-uploads attribute, not just on <img>, <audio>, <video> elements.
  • New mv-upload-url attribute to override the backend-provided URL for the upload.
  • For Plugin Developers: New hooks in upload popup, that make plugins like Cropper possible

UI changes

  • New UI for undoing deletion. Instead of "Item Deleted" elements all over the place, we now use a "toast" notification at the top.
  • Removed Mavo logo from toolbar

MavoScript changes

  • Better error reporting for expressions: Separate errors for syntax mistakes and errors during expression evaluation. The former only appear once in the console.
  • Smart property resolution now also works for "hidden" data that is not rendered on any HTML. This way you can have multiple Mavos that work on the same data and calculate things based on that data without having to add properties that you never intend to display.

New operators

  • New where operator and corresponding filter() function for filtering lists of values.
  • New in operator and corresponding has() function for searching in lists of values or groups
  • New .. operator for generating lists of integers, and corresponding range() function with more parameters (namely, a step)
  • New experimental by operator and corresponding groupBy() function, thanks to @jwass91

New special properties

  • New $item special property which always returns the closest collection item
  • New $all special property which can be used in two ways: a) By itself it returns all items of the closest collection b) after another property (like foo.$all), which returns all values of foo
  • New $this special property for the current group, useful in conjunction with where
  • Special properties are now also available without a $, albeit with lower priority (to avoid collisions with other types of variables). E.g. instead of $next, you can also use next. It's still recommended to use the $ anyway, for clarity.

New functions and improvements on existing functions

  • list() and group() functions for imitating the kinds of data that comes from collections and groups (for those who know JS or JSON: list(1, 2, 3) is analogous to [1, 2, 3] and group(name: 'Lea', age: 33) to {"name": "Lea", "age": 33})
  • New contains() function for searching entire objects and lists, thanks to @efeichen
  • New split() function for splitting text into a list (the opposite of join())
  • New random() function for generating random numbers
  • New median() function for calculating the median of a list of values
  • New phrase() function for custom localized text
  • Almost every Mavo function now works with lists of values as well, thanks to @efeichen
  • Optional n argument in first(n, list) and last(n, list) for how many first/last items to return (if omitted it defaults to 1)

Other changes

  • New mv-expressions-ignore attribute to ignore expression syntax (usually brackets) inside a specific attribute. E.g. to use a data URI with JSON inside mv-storage without its brackets interfering with expressions, you can just do mv-expressions-ignore="mv-storage". In the past, the only way to do this was to change the expression syntax for the entire element via mv-expressions.
  • Lots of improvements with the Github backend and the edit suggestion (pull request) flow, thanks to @jwass91
  • Simple properties can now contain arbitrary HTML that does not take part in the value of the property. E.g. if you want to have a static image inside your simple property, you can write <span property="foo">Hello <img src="foo.png"></span> and only the "Hello" will become editable.
  • aria-label is now dynamic and can be used to provide custom placeholders
  • Multiple property names are now supported in mv-alias thanks to @jwass91
  • Hundreds of bugfixes
  • Lots of performance improvements with expression evaluation
  • Improvements to memory management, thanks to [@hopef...
Read more

v0.1.6

16 Apr 13:53
Compare
Choose a tag to compare

This is a small incremental release. Huge things coming in the next one though! :)

  • Experimental mv-like="propertyName" attribute for copying templates from another collection. Property names are resolved in the same way as in expressions, except the current element is excluded (otherwise property="foo" mv-like="foo" would refer to itself). Collections created this way always start from 0 elements. Note that this allows infinitely nested collections where the children have the same template as the parent (e.g. comment nesting). In the future we plan to expand this beyond collections. Try it out and report bugs!
  • Experimental mv-optional attribute (boolean attribute, no value) to create collections that start with 0 elements.
  • When pasting an image, you will now be prompted for a filename. The auto-generated filename will still be there as a default.
  • 50% speedup in expression evaluation.
  • Raw GraphQL queries supported in Github backend (read-only, just like all raw API calls). To use, specify a URL like api.github.com/graphql#query{…}
  • ordinal()/th() functions now only return the ordinal part (e.g. "th") without the number. This is to allow for more flexible formatting.
  • Improvements in idify()
  • Several other bugfixes and improvements.

v0.1.5

05 Dec 06:32
Compare
Choose a tag to compare

Breaking changes

Important, the following changes mean you need to modify your code to use this version:

  • $url, which became deprecated in the previous version, is now removed. Please use the url() function instead.
  • The syntax of the mv-bar attribute has changed, although most of the previous syntax still works for compatibility. The yes- prefix will be removed in the next version. Please read about the new mv-bar syntax in the docs.
  • In case you were using identifiers in mv-path to only edit a collection item with that id, you will now need to use id= before it (e.g. mv-path="pages/foo" becomes mv-path="pages/id=foo"). And yes, other properties besides id are now possible too :)
  • For advanced users using Mavo with JS: Event names have changed. You will need to change them in your code or it will stop working. mavo:datachange became mv-change, all other mavo:* events became mv-*.

Other changes:

  • Basic IE 11 support!
  • New Import and Export optional toolbar buttons! Try them out by using mv-bar="with import export" or visit the SVG Path demo which already uses them.
  • The Mavo toolbar now uses position: sticky in browsers that support it, so that it remains visible while its Mavo app is visible. This is especially useful for long Mavo applications, to avoid scrolling up and down to toggle between edit and read modes.
  • The $now special property now updates on every repaint instead of every 100ms, making it possible to use it for smooth animations.
  • New $startup special property, which corresponds to the value of $now when the page loaded.
  • Improved editing popups: Now positioned above the property they are editing if there is no space below, with the arrow pointing downwards.
  • Improved image uploading user experience: Image is now displayed immediately, even before it's uploaded to the remote service.
  • New MavoScript functions: reverse()
  • Backspace (or Shift + Backspace in complex collections) can now delete collection items.
  • For advanced users using Mavo with JS: new mv-edit and mv-done events. Mavo.prototype.dataLoaded promise for when the data has loaded. Mavo.options() utility method for
    loosely parsing key-value pairs.
  • 39 smaller improvements and bugfixes