Skip to content
Maxwell Bates edited this page Mar 18, 2014 · 3 revisions

##Considerations What we are developing is very similar to Web Components (particularly Web Components) and should follow their format

Good Writeup on HTML Imports

W3 - Web Components

W3 Spec - HTML Imports

Polyfill: Polymer

Requirements

Support:

  • dependencies
    • HTML files
    • CSS files
    • Angular Components
    • Script (before load)
    • Script (on load)
    • other static files
  • Dictionary for angular interpolation
  • Choose where to show

Use cases to consider:

  • single image
  • Trail views
  • autonomous widgets

todo

  • better tie-in with Clotho
  • dynamic information (e.g. functions to be run on server)
  • things not exposed to client

Proposed Model + Flow

Overview

Widgets are wrappers which consist of dependencies (scripts, css, html), 'flat files' (images, html, anything really), and data (dictionary, position information).

Dependencies include html partials, css styles, and scripts.

  • HTML partials are HTML which will be compiled by angular (and therefore may use it's templating, directives, etc.)
  • CSS files are simply normal CSS files
  • Scripts may consist of
    • angular-specific
      • angular components (services, factories, directives, controllers, providers, etc.) to add to the parent web app
      • autonomous angular modules and components namespaced by their ID
    • other javascript, e.g.
      • scripts which execute clotho commands (e.g. collect calls)
  • Scripts can be downloaded
    • so they are downloaded only once
    • so they execute immediately upon download
    • execute after widget bootstrap via callback

Files are simply static resources (e.g. images, JSON) that may be included as part of the view. Files will be accessed via REST, namespaced by ID: server/<viewId>/resourceName.ext

Data pertaining to the widget (ID), how to add it (specify DOM location, what modules to require for bootstrap), dictionary (keyvals to extend angular's scope), imported views (linking ID to a key name), etc.

Extensible

Widgets may contain as many or few dependencies as they wish, e.g.:

  • no dependencies
  • a template or CSS file to cache
  • a script which collects a few resources
  • angular module to be shared among several widgets may only have a script dependency
  • an iphone app-like autonomous widget, which is autonomous both in its code and visually

Widgets may list as many or few files as they wish, e.g.:

  • no files
  • a single image
  • a list of images

Widgets as wrappers

Widgets may simply wrap files (potentially listing dependencies).

One file

A view may simply wrap a single file. For example, user X may create a view with viewId=12345 that wraps a portrait image, portrait.png.

That file should be accessible as server/12345/portrait.png BUT ALSO as server/12345 and pass the appropriate MIME-type (png in this case)

Multiple files

A view may wrap several files. For example, user Y may create a view with viewId=98765 that contains portraits for each member of his lab.

User Y adds person1.png and person2.png, which in turn may be accessed as server/98765/person1.png and server/98765/person2.png.

It would not make sense to access server/98765.

Dependencies

A view may list dependencies whether or not it is to be displayed on the page. Dependencies are simply downloaded when specified, and handled according to their type

  • HTML is cached in $templateCache (either parent app or sibling app, depending on implementation - does not make sense outside of bootstrapped app context)
  • CSS is downloaded... callbacks require some overhead but doable if needed
  • javascript is downloaded and executed on load (can specify as callback after bootstrap)
  • definition object is used to extend the $scope for interpolation

Importing Views

An obvious use-case would be importing these wrappers to gain 'local' access to files in the view, obscuring the viewID under a specified name.

For example, User Y later creates another view viewId=abcd. In view abcd, he can declare he wishes to import view 98765 as labPersonnel. This link will be passed as part of the dictionary.

This dependency would allow him to access person1.png in his HTML using angular's interpolation, e.g. <img src="{{labPersonnel}}/person1.png">

Widgets added to the DOM

Widgets which are to be bootstrapped on the screen must specify a bit more information:

  • that they are apps
  • modules they are dependent on

There are 2 primary ways we could handle widgets that are added to the DOM.

  1. Widgets add angular components to the parent webapp (using the clotho.extensions.__ syntax) - or simply run scripts. They can be bootstrapped inside the parent app, using all of its components.
  2. Widgets bootstrap outside the parent app, using the parent app's modules' functionality, or including their own components in a module namespaced by their ID (new modules cannot be added to a bootstrapped app)
  • We may run into namespace problems by letting people add components to the parent app. Hence use of the namespaced module.
  • bootstrapping new apps (I believe) can take place in the parent app. Using a clotho-show directive, I think we can bypass compilation errors of this nature.

Widgets must list the angular modules they depend on (if any). Widgets can use functionality from the parent app by pulling in the relevant modules. If they contain their own module, they must list it. These modules will be used by angular.bootstrap(), so the widget will not bootstrap until they are all downloaded and present, and all modules should be listed to avoid premature bootstrap. They cannot include 'ngRoute' as URL routing will not work in these widgets.

Process

Dependencies are downloaded, the widget bootstrapped using angular.

  • View is requested by its ID, e.g. using Clotho.show()
  • Server loads from database. Some data is JSON, files are opened.
  • Server sends dependencies to client (e.g. as response to Clotho.show() call). Because there are an unknown number of resources in a widget's dependencies, and because we do not want to send resources over the websocket as binaries to parse on the client, the server must notify the client the number of resources and URL at which each may be downloaded.
  • The server can send a list of URLs (temporary, or namespaced by view as described above) which the client will download. Dependencies are handled according to type as defined above.
    • alternatively, send a command to download certain URLs for security reasons (security risk?)
  • After all dependencies downloaded, widget is bootstrapped using angular.bootstrap()... all modules listed must be present for bootstrap to execute
    • certain $providers and $services will be modified or overwritten (e.g. $locationProvider to prevent URL rewrites)
  • callback function called after DOM insertion and linking, executing callback scripts (may make more sense to patch this through PubSub)
  • files (e.g. an image named portrait.png) may be accessed from the HTML directly (e.g. <img src="{{viewId}}/portrait.png">), and may access imported images by namespacing them according to the keyval defined in the import (e.g. <img src="{{importedViewName}}/portrait.png"> routes to server/<importedViewId>/portrait.png)
Clone this wiki locally