Cross-browser app launcher and device toolbar for showing responsive, mobile first web applications on the web or offline. Powered by Mochi and Bootstrap.
The digital sandbox is a portable (i.e., cross-browser) app launcher and device toolbar that allows you to easily display a collection of applications and websites in a programmable iFrame window. It's inspired by Chrome DevTools' device mode feature, but with complete portability (i.e., can be used offline or online in most Internet browsers).
Mochi is a ready-to-deploy HTML5 boilerplate framework that runs on Bootstrap, but adds tons of new features, with a strong focus on offline web applications without all the limitations. It achieves this goal by fully integrating and maintaining offline versions of popular libraries that have been out in the wild for years.
To use the digital sandbox, simply download the latest distribution package and extract the contents of the included dist
folder to the root of your website directory (e.g., /var/www/html
in some systems). That's it! You now have a fully functioning and completely portable device toolbar installed on your website. The digital sandbox is designed to run either online or offline, depending on your desired configuration.
Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations for all libraries. You'll see something like this:
dist/
βββ bootstrap/
β βββ css/
β β βββ bootstrap.css
β β βββ bootstrap.min.css
β β βββ bootstrap-grid.css
β β βββ bootstrap-grid.min.css
β β βββ bootstrap-reboot.css
β β βββ bootstrap-reboot.min.css
β β
β βββ js/
β βββ bootstrap.bundle.js
β βββ bootstrap.bundle.min.js
β βββ bootstrap.js
β βββ bootstrap.min.js
β
βββ frontend/
β βββ apps/
β β βββ demos/
β β β βββ starter-template/
β β β βββ index.html
β β β
β β βββ README.txt
β β
β βββ css/
β β βββ print.css
β β βββ style.css
β β
β βββ img/
β β βββ brand/
β β β βββ launcher-icon-1x.pmg
β β β βββ launcher-icon-4x.pmg
β β β
β β βββ web/
β β βββ devices/
β β β βββ apple/
β β β β βββ ipad.png
β β β β βββ ipad_air.png
β β β β βββ ipad_air-l.png
β β β β βββ ipad_mini.png
β β β β βββ ipad_mini-l.png
β β β β βββ ipad_pro_9_7.png
β β β β βββ ipad_pro_9_7-l.png
β β β β βββ ipad_pro_12_9.png
β β β β βββ ipad_pro_12_9-l.png
β β β β βββ ipad-l.png
β β β β βββ iphone_5s.png
β β β β βββ iphone_5s-l.png
β β β β βββ iphone_6plus.png
β β β β βββ iphone_6plus-l.png
β β β β
β β β βββ google/
β β β β βββ nexus_7.png
β β β β βββ nexus_7-l.png
β β β β βββ nexus_10.png
β β β β βββ nexus_10-l.png
β β β β
β β β βββ samsung/
β β β βββ galaxy_s5.png
β β β βββ galaxy_s5-l.png
β β β
β β βββ walls/
β β β βββ bulbs.png
β β β βββ desk.png
β β β βββ landscape.png
β β β
β β βββ tile.png
β β
β βββ js/
β β βββ config.js
β β βββ onload.js
β β βββ onload.min.js
β β
β βββ less/
β β βββ _2dppx_375up.less
β β βββ _2dppx_425up.less
β β βββ _2dppx_480up.less
β β βββ _2dppx_576up.less
β β βββ _2dppx_640up.less
β β βββ _2dppx_750up.less
β β βββ _2dppx_768up.less
β β βββ _2dppx_970up.less
β β βββ _2dppx_992up.less
β β βββ _2dppx_1020up.less
β β βββ _2dppx_1024up.less
β β βββ _2dppx_1170up.less
β β βββ _2dppx_1200up.less
β β βββ _2dppx_1440up.less
β β βββ _2dppx_1560up.less
β β βββ _2dppx_2560up.less
β β βββ _2dppx_base.less
β β βββ _375up.less
β β βββ _425up.less
β β βββ _480up.less
β β βββ _576up.less
β β βββ _640up.less
β β βββ _750up.less
β β βββ _768up.less
β β βββ _970up.less
β β βββ _992up.less
β β βββ _1020up.less
β β βββ _1024up.less
β β βββ _1170up.less
β β βββ _1200up.less
β β βββ _1440up.less
β β βββ _1560up.less
β β βββ _2560up.less
β β βββ _base.less
β β βββ _mixins.less
β β βββ _notouch.less
β β βββ _print.less
β β βββ print.less
β β βββ style.less
β β
β βββ themes/
β βββ default/
β βββ css/
β β βββ print.css
β β βββ style.css
β β
β βββ less/
β β βββ _2dppx_375up.less
β β βββ _2dppx_425up.less
β β βββ _2dppx_480up.less
β β βββ _2dppx_576up.less
β β βββ _2dppx_640up.less
β β βββ _2dppx_750up.less
β β βββ _2dppx_768up.less
β β βββ _2dppx_970up.less
β β βββ _2dppx_992up.less
β β βββ _2dppx_1020up.less
β β βββ _2dppx_1024up.less
β β βββ _2dppx_1170up.less
β β βββ _2dppx_1200up.less
β β βββ _2dppx_1440up.less
β β βββ _2dppx_1560up.less
β β βββ _2dppx_2560up.less
β β βββ _2dppx_base.less
β β βββ _375up.less
β β βββ _425up.less
β β βββ _480up.less
β β βββ _576up.less
β β βββ _640up.less
β β βββ _750up.less
β β βββ _768up.less
β β βββ _970up.less
β β βββ _992up.less
β β βββ _1020up.less
β β βββ _1024up.less
β β βββ _1170up.less
β β βββ _1200up.less
β β βββ _1440up.less
β β βββ _1560up.less
β β βββ _2560up.less
β β βββ _base.less
β β βββ _mixins.less
β β βββ _notouch.less
β β βββ _print.less
β β βββ print.less
β β βββ style.less
β β
β βββ onload.js
β
βββ mochi/
β βββ css/
β β βββ helpers/
β β βββ animate.less/
β β βββ dist/
β β βββ css/
β β β βββ animate.css
β β β
β β βββ less/
β β βββ _mixins.less
β β βββ _options.less
β β βββ animate.less
β β
β βββ js/
β β βββ helpers/
β β β βββ font-awesome-free/
β β β β βββ js/
β β β β βββ all.min.js
β β β β
β β β βββ iScroll/
β β β β βββ build/
β β β β βββ iscroll.js
β β β β βββ iscroll.min.js
β β β β βββ iscroll-infinite.js
β β β β βββ iscroll-infinite.min.js
β β β β βββ iscroll-lite.js
β β β β βββ iscroll-lite.min.js
β β β β βββ iscroll-probe.js
β β β β βββ iscroll-probe.min.js
β β β β βββ iscroll-zoom.js
β β β β βββ iscroll-zoom.min.js
β β β β
β β β βββ ViewerJS/
β β β β βββ images/
β β β β β βββ kogmbh.png
β β β β β βββ nlnet.png
β β β β β βββ texture.png
β β β β β βββ toolbarButton-download.png
β β β β β βββ toolbarButton-fullscreen.png
β β β β β βββ toolbarButton-menuArrows.png
β β β β β βββ toolbarButton-pageDown.png
β β β β β βββ toolbarButton-pageUp.png
β β β β β βββ toolbarButton-presentation.png
β β β β β βββ toolbarButton-zoomIn.png
β β β β β βββ toolbarButton-zoomOut.png
β β β β β
β β β β βββ tools/
β β β β β βββ replaceByFileContents.js
β β β β β
β β β β βββ example.local.css
β β β β βββ HeaderCompiled.html
β β β β βββ HeaderCompiled.js
β β β β βββ index.html
β β β β βββ index-template.html
β β β β βββ ODFViewerPlugin.css
β β β β βββ ODFViewerPlugin.js
β β β β βββ PDFViewerPlugin.css
β β β β βββ PDFViewerPlugin.js
β β β β βββ PluginLoader.js
β β β β βββ viewer.css
β β β β βββ viewer.js
β β β β βββ viewerTouch.css
β β β β
β β β βββ basil.min.js
β β β βββ Chart.bundle.min.js
β β β βββ clipboard.min.js
β β β βββ holder.min.js
β β β βββ modernizr-custom.js
β β β βββ popper.min.js
β β β βββ sprintf.min.js
β β β βββ underscore.string.min.js
β β β βββ underscore-min.js
β β β
β β βββ jquery/
β β β βββ ui/
β β β β βββ images/
β β β β β βββ ui-icons_444444_256x240.png
β β β β β βββ ui-icons_555555_256x240.png
β β β β β βββ ui-icons_777620_256x240.png
β β β β β βββ ui-icons_777777_256x240.png
β β β β β βββ ui-icons_cc0000_256x240.png
β β β β β βββ ui-icons_ffffff_256x240.png
β β β β β
β β β β βββ jquery-ui.css
β β β β βββ jquery-ui.js
β β β β βββ jquery-ui.min.css
β β β β βββ jquery-ui.min.js
β β β β βββ jquery-ui.structure.css
β β β β βββ jquery-ui.structure.min.css
β β β β βββ jquery-ui.theme.css
β β β β βββ jquery-ui.theme.min.css
β β β β
β β β βββ jquery.min.js
β β β
β β βββ plugins/
β β β βββ dialog/
β β β β βββ dist/
β β β β βββ dialog.js
β β β β βββ dialog.min.js
β β β β
β β β βββ veeva/
β β β βββ dist/
β β β βββ veeva.js
β β β βββ veeva-library.js
β β β βββ veeva-library.min.js
β β β βββ veeva.min.js
β β β
β β βββ libraries.js
β β βββ mochi.js
β β βββ mochi.min.js
β β
β βββ less/
β βββ _2dppx_375up.less
β βββ _2dppx_425up.less
β βββ _2dppx_480up.less
β βββ _2dppx_576up.less
β βββ _2dppx_640up.less
β βββ _2dppx_750up.less
β βββ _2dppx_768up.less
β βββ _2dppx_970up.less
β βββ _2dppx_992up.less
β βββ _2dppx_1020up.less
β βββ _2dppx_1024up.less
β βββ _2dppx_1170up.less
β βββ _2dppx_1200up.less
β βββ _2dppx_1440up.less
β βββ _2dppx_1560up.less
β βββ _2dppx_2560up.less
β βββ _2dppx_base.less
β βββ _375up.less
β βββ _425up.less
β βββ _480up.less
β βββ _576up.less
β βββ _640up.less
β βββ _750up.less
β βββ _768up.less
β βββ _970up.less
β βββ _992up.less
β βββ _1020up.less
β βββ _1024up.less
β βββ _1170up.less
β βββ _1200up.less
β βββ _1440up.less
β βββ _1560up.less
β βββ _2560up.less
β βββ _base.less
β βββ _mixins.less
β βββ _notouch.less
β βββ _print.less
β
βββ .htaccess
βββ index.html
βββ manifest.json
βββ offline.html
βββ project.appcache
βββ robots.txt
βββ sw.js
The included configuration file (dist/frontend/js/config.js
) is a great way to get started with using the digital sandbox. This file acts as your digital sandbox controller center, and uses special variables to organize your apps in a consistent, accessible format. Additionally, this is where you would include the basic HTML markup that allows the sandbox work to generate the app launcher screen (i.e., the inline frame). Continue reading below to learn how the standard HTML template should be structured to take full advantage of the sandbox.
Note: A full list of supported variables are listed here.
First things first! After the unified configuration file is loaded and processed, the digital sandbox will determine if the included HTML body markup matches this basic structure:
<div class="row">
<div class="col-sm-6">
<div data-title="Demos">
<a href="./?demos:my-first-app:v1.0/index">My First App v1.0</a>
<a href="./?demos:my-first-app:v2.0/index">My First App v2.0</a>
<a href="./?demos:my-first-app:v3.0/index">My First App v3.0</a>
</div>
</div>
<div class="col-sm-6">
<div data-title="Websites">
<a href="https://google.com/">Google</a>
</div>
</div>
</div>
If it does, it will automatically be converted to something like this:
<div class="row">
<div class="col-sm-6">
<div class="ds-widget ds-widget-simple" id="ds-widget-simple-0">
<div data-bucket="demos">
<h1>Demos</h1>
<table class="table table-sm table-bordered table-hover">
<tbody>
<tr>
<td><a target="_top" title="My First App v1.0" href="./index.html?demos:my-first-app:v1.0/index">My First App v1.0</a></td>
<td title="Launch Internal"><a target="_top" href="./index.html?demos:my-first-app:v1.0/index"><i class="fas fa-sign-in-alt"></i></a></td>
<td title="Launch External"><a target="_blank" href="http://mydomain.com/frontend/apps/demos/my-first-app/v1.0/index.html"><i class="fas fa-link"></i></a></td>
</tr>
<tr>
<td><a target="_top" title="My First App v2.0" href="./index.html?demos:my-first-app:v2.0/index">My First App v2.0</a></td>
<td title="Launch Internal"><a target="_top" href="./index.html?demos:my-first-app:v2.0/index"><i class="fas fa-sign-in-alt"></i></a></td>
<td title="Launch External"><a target="_blank" href="http://mydomain.com/frontend/apps/demos/my-first-app/v2.0/index.html"><i class="fas fa-link"></i></a></td>
</tr>
<tr>
<td><a target="_top" title="My First App v3.0" href="./index.html?demos:my-first-app:v3.0/index">My First App v3.0</a></td>
<td title="Launch Internal"><a target="_top" href="./index.html?demos:my-first-app:v3.0/index"><i class="fas fa-sign-in-alt"></i></a></td>
<td title="Launch External"><a target="_blank" href="http://mydomain.com/frontend/apps/demos/my-first-app/v3.0/index.html"><i class="fas fa-link"></i></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="ds-widget ds-widget-simple" id="ds-widget-simple-1">
<div data-bucket="websites">
<h1>Websites</h1>
<table class="table table-sm table-bordered table-hover">
<tbody>
<tr>
<td><a target="_blank" title="Google" href="https://google.com/">Google</a></td>
<td title="Launch Internal"><span class="text-muted"><i class="fas fa-sign-in-alt"></i></span></td>
<td title="Launch External"><a target="_blank" href="https://google.com/"><i class="fas fa-link"></i></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
And there you have it! We call this type of conversion "widgetization of the app directory". Once widgetized, the digital sandbox will organize your apps in a structured format that's usable by most modern browsers. You can define which widget you'd like to use by modifying the LAUNCHER_WIDGET_NAME
variable in the unified configuration file. See below for a list of supported widgets.
The following widgets are supported in the standard distribution package:
Widget Name | Description |
---|---|
simple |
Organizes your apps in a basic table structure. This is the default widget. |
accordion |
Organizes your apps as Bootstrap-powered accordions. |
In addition to allowing you to widgetize the app directory, the digital sandbox also supports a unique query string format for customizing the way your apps are appear within the iFrame window. Consider the following example:
To launch dist/frontend/apps/demos/my-first-app/v1.0/home.html
as an iPad device in portrait orientation, you would navigate to the following URL:
./index.html?demos:my-first-app:v1.0/home~ipad:p|demos&title=Welcome
The URL above would produce an iFrame window configured as:
- a wrapped window in a device image referenced as
ipad
(i.e., a standard iPad), and - with the
ipad
device image set toportrait
orientation, and - ensuring the digital sandbox is aware the app is located under the
demos
folder, which would - allow the sandbox to refer back to the folder when the user interacts with the toolbar, and
- making sure the app link always refreshes the iFrame parent window, and
- the
home.html
file indist/frontend/apps/demos/my-first-app/v1.0
is opened, and - ensure the browser tab label is set to "Welcome".
Because the digital sandbox is built with Bootstrap, learning to use it is as easy as digging into their official docs and mastering the awesome features provided by the framework. We encourage you to head on over to the official Bootstrap documentation to learn like a pro. Happy coding!
This project is licensed under the MIT license. (http://opensource.org/licenses/MIT)