Giter Site home page Giter Site logo

hax-body's Introduction

<hax-body></hax-body>

Published on webcomponents.org

HAX

Headless Authoring eXperience or HAX for short, is a new way of authoring content that works across platforms. Written in webcomponents, HAX allows users to effectively write HTML by touching the interface directly. Think WYSIWYG if it was built with modern and future proof tools and libraries instead of based on the work of the early 2000s.

HAX can be integrated into any solution as it's depending on a headless backend in order to integrate. It also has the ability to allow end users to use and insert complex custom elements, presenting an input form based on JSONSchema that's emmitted from the custom element upon registration. HAX is for stitching together your universe of content and media solutions into a remote control for your authors.

There's lots of documentation in this file and examples of integrations and you can see lots of video based tutorials in this playlist: https://www.youtube.com/watch?v=kLrKMhz8-JY&list=PLJQupiji7J5eTqv8JFiW8SZpSeKouZACH

Notable video examples / tutorials for building

Deeper developer dive into how HAX works

An application that uses HAX is made up of several custom elements working together. Some of the primary elements to make this happen are:

<hax-body>
<hax-panel>
<hax-manager>
<hax-source>
<hax-autoloader>
<hax-store>

These elements all live at the "app level" that you will create in order to utilize these tags. They are separate so that you can swap them out or fork individual ones as you desire.

Systems that integrate with HAX

Can I build my own elements for HAX?

YES! HAX's "gizmo" and "app store" systems are 100% pluggable. The app store concept has it's own API for creation which can best be modeled by looking at the example appstore.json from the demo (all the CMSs that integrate with HAX also can serve up this store data). See example here.

What about Gizmo's tho...

Gizmo's are just a silly word for Custom Elements (so we don't use that word over and over again). To make a Gizmo you just make a custom element. The HAX playlist has tons of examples of doing this across the many elements we demonstrate in the demo. To build your own it's probably best to see the integration in one of those videos or you can read the integration specification from hax-body-behaviors. HAX can talk to anything and your implementation of HAX can specify exactly the custom tags you want it to understand.

Polymer tutorials

https://www.youtube.com/watch?v=QGOPsqVjGjU - learn polymer from the people making this

What do I need to integrate with hax?

HAX is designed to integrate with any system by being about authoring HTML that any end user could have hit "view source" and done themselves. It manipulates the DOM in a targetted area and then bubbles up what the change was without all the HAX cruft attached. If you want to get more integrations listed above, here's what the system needs:

  • HTML blob storage - It has to store data as a block of HTML. If it has a CKEditor or TinyMCE input method currently then it probably does this already.
  • ability to render webcomponents - hax is built on webcomponents so your system has to be able to load them (this is as easy as adding an <link rel="import" src="cms-hax/cms-hax.html"/> reference)
  • end point / API location to save the data (if building your own HAX integration not the cms or wysiwyg option)

If you think you can use HAX, try one of the methods below of integration. HAX is a pretty deep dive into Polymer / Webcomponents so these areas might be good starting points and then working down from there if you find it useful.

Drop in integrations

Why the difference in integration methodologies?

hax-body is a collection of tags for building your own HAX editor. You don't like our hax-panel tag? Well, if you implement the registration function for your own much-better-hax-panel tag then it'll act like it's part of HAX. This isn't for everyone though so we have some simplified integrations that are much less flexible (they define and implement the standard tags of hax). ELMS:LN for example implements hax-body and associated tags directly but the other integrations listed utilize cms-hax. For a complex example integrating with the tags directly into an existing application, check out https://github.com/elmsln/elmsln/blob/0.10.x/core/webcomponents/apps/lrnapp-book/src/lrnapp-book/lrnapp-book.html .

Definitions

  • HAX - Headless Authoring eXperience or HAX, will always and must always be system agnostic. It needs to be able to interface with HTML primatives as well as custom-element tags which provide a haxProperties object to the specification of a haxElement.
  • HAX Element - a sanitized simple object representation of a DOM node. HAX Elements can be translated into full DOM nodes easily because they express tag, properties and content. The element also allows for easy manipulation of an item prior to it ever existing in the DOM. Here's an example of a HAX Element to illustrate (using video-player as an example).
{
    "tag": "video-player",
    "properties": {
        "source": "https://www.youtube.com/watch?v=bzH4seWf8rQ"
        "responsive": false
    },
    "content": ""
}
  • JSON schema - is a way of expressing the validation and input of properties in a JSON object, using a JSON object to express it (yeah.. I know..). What this affords us is a way of automatically generating form fields to modify the custom element fields that have been defined in the haxProperties object. This relationship can be seen in the hax-preview element which will map haxProperties to JSON Schema in order to generate an input form for the element. A fork eco-json-schema-form is providing all form capabilities to interface with the schema.
  • haxProperties - an object that lives on a HAX capable element, expressing the way to build forms in HAX to modify it's options. This object expresses a default HAX Element, some minor booleans for UI areas, and the settings object which defines the field / property mapping for the quick, configure and advanced forms.
    • quick settings - these appear on the bar in place when an element has focus in hax-body
    • configure settings - these appear on the hax-preview form by default. Think of these as your primary means of modifying this "content type" so to speak, if the custom element were a unique piece of content to the system
    • advanced settings - things outside the norm as well as the "source view" if that boolean has been set
  • Gizmo - A gizmo is a custom element placed in the page that provides advanced functionality. This could be a calendar widget, or a pdf-element, or a video-player, or really anything beyond a primative. This is effectively our silly name we use to communicate to end users adding something cool.
  • Stack - A stack is a series of hax-blox, HTML primatives, and custom elements. Think of it like a "template" in other systems. It's just stamping down a series of things which can then be modified on their own. It's meant to be forked and not maintained after stamping. An example could be a standard page layout with an image justified to the right and broken out into three paragraphs.

element scope / definitions

  • <hax-body-behaviors> - any element that wants to be wired to HAX (in the polymer universe) should use hax-body-behaviors in order to provide consistency of property names, functions and utility functions.
  • <hax-body> - the body area that all of the magic happens within. This is the thing providing the content for manipulation and injection of things.
    • <hax-blox> - a layout element that can help group the elements with in it
    • <hax-ce-context> - figures out the options for a custom element by reading off of the haxProperties object on the custom element.
      • <hax-input-mixer> - handles the data binding / form element type for an in-place change. This helps the "quick" options actually have an authoring UI
    • <hax-iframe-context> - quick context menu for the iframe primative
    • <hax-image-context> - quick context menu for the img primative
    • <hax-text-context> - quick context menu for anything that is valid yet doesn't have a dedicated menu. This would be things like p, blockquote, code, h[1-6].
    • <hax-plate-context> - a grid-plate editor which allow for cloning the item, moving it up or down in the hax-body DOM or deleting the element from the body
    • <hax-context-item> - an icon button for any hax-*-context menus which emmits normalized events and provides display consistency
    • <hax-context-item-textop> - same as hax-context-item but this is specific to text-based operations. If the event needs to maintain focus on the element's contenteditable area in order to work (like injecting a bulleted list) then this button helps ensure that happens. It works in all the same ways otherwise.
    • <hax-context-item-menu> - providing a consistent drop-down menu in place
  • <hax-panel> - side panel of options to pick from as a form of quick inserting and selection of HAX Elements that get inserted into hax-body.
    • <hax-panel-item> - an item that lives in hax-panel and helps provide visual consistency as well as normalized event bubbling
  • <hax-manager> - modal that's doing the bulk of the work of finding and configuring an element before it is placed on the page
    • <hax-source-browser> - a listing of all hax-sources in a "app store" type display
      • <hax-source-browser-item> - an item in this listing, generated based on reading off the information provided by hax-source
    • <hax-gizmo-browser> - a listing of all gizmos in a "app store" type display for presenting and managing searching for gizmos the end user can add to the body of content.
      • <hax-gizmo-browser-item> - an item in this listing, generated based on reading off the information provided by custom elements implementing haxProperties.
    • <hax-preview> - the "configure" screen of hax-manager which shows an interactive preview of what your working on and tweaking
  • <hax-source> - an end point that has a listing of items (like videos) which also expresses
  • <hax-store> - a state management object store as well as brain for what elements and sources are available to this HAX application. For example, if you place a <video-player> tag inside the <hax-store> element on the page, it will realize that video-player is a valid element, import it's definition at run-time (lazy load) as well as start to build up HAX defintion of what elements are available in the <slot>. It also provides global transformation methods for things like HaxPropertiesToJSONSchema and HAXElementToNode. This is the brain helping everyone else have to do less.

Interaction flow

User clicks an edit button of some kind to enable HAX by placing hax-body into edit-mode (property). The user then can either click on elements currently in hax-body or to add new elements, click in hax-panel. As hax-body is pretty self contained, we won't express what's going on there but you can see how the different context menus place themselves correctly on active element and maintain wiring between the element and form properties.

hax-body to hax-manager flow

The only meaningful interaction between hax-body and app level elements is that if <hax-ce-context> is being displayed for a custom element and the user clicks the settings button, it will open the <hax-manager> tag to the <hax-preview> element and open to the configure page. If the user hits update it'll update the selected item in the DOM with their modifications.

Adding new things via hax-panel

User clicks on an item in <hax-panel> to add something to the interface, event bubbles up for hax-item-selected event which the app notices. The app can then tell <hax-body> to insert a simple HAX Element if it's an HTML primative (p, h2, blockquote, hr sorta thing) OR, if it's a call for a Gizmo and then it invokes <hax-manager> to open after resetting it to it's default state.

The user then selects if they want to Add material or Browse sources of gizmos. Browsing pulls up the <hax-source-browser> which provides a searchable list of sources in an "App store" style format. "Search Gizmos".

If an gizmo source is selected (we'll say Youtube). It opens a collased area which has search / filter capabilities for that source. The user searches for something, and then clicks on the thing they want to make. Now, the interaction transitions to hax-preview but let's detour quickly and talk about what happened there.

<hax-source> said "I have a HAX element" and bubbles up a hax-source-selected event to the app. The app saw the event and handled it (so it can do custom stuff if needed) and then told <hax-manager> "hey, here's your active thing" which then shifts it forward to the configure step of the operation. As part of this, it will then pass in an element in HAX Element format which <hax-preview> will unpack into the real thing.

hax-preview

This is our form / modification area. hax-preview takes a HAX Element, reads off it's haxProperties object, and then converts it into JSON Schema to generate a form for editing via <eco-json-schema-form>. Preview then converts the HAX Element into a DOM node to render a preview and data binds it to the form. Now as the user edits fields in the form, it'll update the preview.

Once the user likes what they see, they hit embed and it'll convert the preview DOM node into a HAX Element and bubble up an event to insert it into <hax-body> via the app. At this point, <hax-manager> is triggered to close and we've effectively gone end to end.

Saving

There's a function on <hax-body> called haxToContent which will strip all the hax specific tags and meta-data off of the DOM nodes in <hax-body>'s <slot> area and then returns the raw HTML.

And we've done it! Now we can ship this off to a back-end to do whatever we need to in order to save this.

hax-body's People

Contributors

btopro avatar cleverington avatar heymp avatar nikkimk avatar starryeyez024 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hax-body's Issues

Add a code-pen element

code pen has some pretty nice, simple "APIs" that are really just forming a web request correctly. Let's make it a web component and then allow people using HAX to be able to pull in code pens w/ configurable options more easily. You could also use the POST api to build things in HAX and invoke them via the API but let's not get ahead of ourselves...

https://blog.codepen.io/documentation/features/embedded-pens/#postmessage-api

https://blog.codepen.io/documentation/api/prefill/

https://blog.codepen.io/documentation/api/url-extensions/

Editing Existing Links (user experience)

When I highlight an existing link there's no way to see what it's linking to (for example, if I want to change it or if I forget what I put there). Highlighting and clicking the link button brings up a blank box to paste a new link. Would be nice if it showed what was linked there (I believe this is something wordpress does, so maybe there's something out there that's easy to swap in).

Creating text area on pressing the return key

Raising this as a discussion point really in terms of content writing flow.
When typing out content within a text area, should a new paragraph tag (text area) be generated when pressing the return key, rather than a div within the paragraph tag? And if so, would potentially require support for a break tag within the text area config options.

Add element to analyze and notify about alt text

if alt text has "photo" or "image" or "picture" or nothing. Then we should give a message that suggests "hey there might be a problem here". It's entirely possible to have an image that shouldn't have alt or that just says "picture of students" which a screen reader will say as "image. picture of students". In this regard image image, is annoying. We could suggest wording more like "Students sitting under a tree" sort of thing, assuming it says image.

We also don't want to block image, picture, photo, but it's nice to at least nudge people in the right direction. This would also be a good time to link off to related documentation to make it a teachable moment (alt text is blank, Click here to learn more about how you should construct alt data).

Support inline element types

We support block element level additions. We need to support highlighting and applying to an area. Example use-cases:

  • editorial-comment which would allow for editorial comments to be stored with the content
  • lrn-vocab - applying a wrapping tag in a span like manner which could allow for in place vocabulary words or contextual help

Make drupal entity tag

Makes an entity after selecting type which then loads json schema so that it has some level of validation

Comment workflow for author collaboration

Following on from discussion in #3

For the comments workflow - we use Diigo (https://www.diigo.com) currently to collaborate by adding comments and highlights to the screen and that works in much the same way:

image
image

So this works by highlighting some text initially - then a mini pop up appears allowing you to make the highlight, comment or search:

image

The only drawback with this method is the mini pop up tends to get in the way a lot when you're not actually wanting to comment on anything - so you might want to have a 'comment-mode' in the same way as you have an 'edit-mode' where that type of thing exists

async needs a timeout on safari / firefox

certain UI elements need more time to wait for the element to be attached to the DOM correctly before propagating. For example, hitting settings needs to wait, they call up the active element. This happened when we switched to using the store which then has to populate all the elements to keep the data model in sync but provides a slight delay at times.

abstract hax-source-search from hax-source

hax-source-search

  • all the visual side of hax-source
  • make the template stamp in via templatizer

hax-source

hax wide changes

  • source selected needs to just be set and then hax-source-search needs notified of this wiring change (perhaps via some kind of active-connection object or something)
  • we need global registration for hax-source-search as far as the source-search object attaching to the hax-store. This way people could swap it out

copy and paste in text generates fake span tags for no reason

If copying "Each Word" from inside the content and then pasting it inside the content again it will wrap each word in a span like so.
<span style="font-size: 19.2px;">Each</span><span style="font-size: 19.2px;">Word</span>

... very. very strange.

Selection un-selects

After changing the style of selected text, the text is unselected. It would be nice if it remained selected so that other styles could be applied, links added, list creation, etc.

Make a drupal token tag

<drupal-token token="[things:1|entity:2|]"></drupal-token>

This tag will go make a backend request. to get the token, leveraging a Drupal global setting in javascript. Then it'll replace the guts of itself with the token after doing a server side render of the information. This way it'll work with ANY token that we need to preserve

add a embed tag of some kind

like an advanced form of iframe that's responsive. right now we are abusing the video-player for this purpose but it doesnt make much sense

expand and refactor hax-source

hax-manager currently builds out a whole input source selection interface when handed a bunch of JSON wiring. It allows us to talk to effectively anything and normalize it back into a display. It's cool, but needs some serious refactoring for our needs.

Needs / problems currently:

  • currently only handles simple string querying
  • no filter capabilities
  • no auto-loading of remote response (so like a list to filter locally vs continuous querying)
  • forced to only search once 4 characters typed (should be flexible and delayed on value change)
  • needs support for pagination / limiting of result set
  • could easily be made to understand how to do POST operations to allow for uploading

Refactoring needs:

  • how we store the parameters for hitting an end point need consolidated
  • how we do POST / PUT / GET / other CRUD operators need to be expressed
  • search area should be it's own tag to simplify logic
  • iron-list should be a tag (like hax-source-listing made up of hax-source-listing-item kinda thing)
  • wiring to do the ajax call could be each crud operator

hax-option-selector

  • a small modal of options that pops up to provide what to pick
  • needed when there's more then one possible gizmo or endpoint to ship a file to
  • title
  • option='[
    {
    "label":"Youtube",
    "icon":"",
    "color":"",
    "description":"",
    "key":""
    },
    {
    "label":"",
    "icon":"",
    "color":"",
    "description":"",
    "key":""
    },
    ]'

Feedback: Usability of the Video Gizmo

The target click area of the YouTube gizmo, when in editing mode, should be increased to improve usability. Currently, the only way to edit the video is by clicking a small button to the left of the gizmo.

.responsive-video-container.video-player {
    max-width: 500px;
}

video-width

add slot wiping parameter to HAX schema spec

the default case for elements is that on save, it should wipe out the shady/shadow DOM from the "innerHTML" call in order to ensure that it's not going to save things that will unpack again. generally speaking, we want to get rid of these contents but NOT the <slot> area. However, there are edge cases where we want to wipe out <slot> as well. This is when an element dynamically generates it's contents. drupal-token has this ability and as such would preserve it's slot info even though that's supposed to be rebuilt every time.

Ensure no stack order context issues with paper dialogs

Don't all have to be the same but all dialogs should point to our own hax-dialog that is stacking and accessibility safe just like the lrnsys-dialog. Doesn't need all the bells and whistles of that one though. PanEl also needs to be stacling safe, possibly like how other things self append on insert to the body

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.