Lens 2 Internal Documentation
See the front page of the API documentation for how to create and run Lens applications.
Loading Lens Dynamically
http://lens2.lens/dist/latest/lens.js
is a compiled version of Lens. The
webserver automatically compiles Lens using the RequireJS optimizer if any files
have changed since the last time lens was requested. This compilation step takes
about 10 seconds. If you're not working on Lens itself, that should be fine--
it'll just be slow to load the first time you load an app after pull a new
version of Lens. However, if you're doing work on Lens, you probably don't want
to wait 10 seconds on each refresh. In that case, you can use require.js to load
the uncompiled Lens dynamically. Use this script tag:
<script type="text/javascript"
src="http://lens2.lens/lib/require.js"
data-main="http://lens2.lens/src/lens.js"
data-app-main="demo.js"></script>
Where data-app-main
is the path to your main Javascript file (which can then
call Lens.init
and use Lens). The caveat of this method is that Lens will leak
the global variables require
, define
, and requirejs
, which will cause
conflicts if your app uses RequireJS. All the apps in apps/demos
load Lens this way, so it's recommended that you work with the demo apps while
you're editing Lens, and then use http://lens2.lens/dist/latest/lens.js
when
working on non-demo apps.
Lens Toolchain
The toolchain consists of a set of scripts in the scripts
directory. They are
designed to be run with the lens
directory as the working directory.
Documentation
The documentation can be generated with scripts/gen-docs.sh
. You'll need to
have a jsdoc
command in your PATH that run jsdoc-toolkit. On Ubuntu,
sudo apt-get install jsdoc-toolkit
will do the trick. The API docs can be
opened with scripts/api-docs.sh
and the internal docs can be opened with
scripts/internal-docs.sh
Unit Tests
The test suite can be run with scripts/test.sh
. The test suite is not
currently maintained.
Lens Conventions
Source Layout
README.md This file
docs/ Autogenerated documentation
docs/api/ Public API documentation
docs/internal/ Internal documentation
scripts/ Development toolchain scripts
src/ Source code
lens.js The main loader for Lens -- apps include this directly
ARCore.js The loader for ARCore. Loaded by default by Lens.init
Components.js Loaded by apps that want all Components.
LAF.js Loaded by apps that want the LAF toolkit.
common/ Common utilities and classes shared by all of Lens
ARCore/ Core modules that expose specific backend capabilities.
Components/ Standalone UI componenets
LAF/ The Lens Look-and-Feel toolkit.
fonts/ Font options for the LAF toolkit.
icons/ Icon set options for the LAF toolkit.
palettes/ Palette options for the LAF toolkit.
widgets/ Widgets provided by the LAF toolkit.
lib/ Third-party javascript libraries.
test/ Unit test suite
Module Conventions
When creating a new module, use one of the following templates.
Public Module
/**
* My Module!
* @namespace
* @name Lens.MyModule
*/
define(["dep1", "dep2"], function(dep1, dep2) {
"use strict";
var privateStaticMethod() {
// ...
}
var privateStaticVariable = 10;
var MyModule = /** @lends Lens.MyModule */ {
/** Does cool stuff */
publicFunction: function() {
// ..
}
}
Object.freeze(MyModule);
// Choose one:
// Lens._addMember(MyModule, "MyModule"); // for ARCore
// Lens._addMember(MyModule, "MyModule", Lens.LAF); // for LAF
// Lens._addMember(MyModule, "MyModule", Lens.Components); // for Componenets
return MyModule;
});
Public Classes
define(["dep1", "dep2", "lib/underscore"], function(dep1, dep2, _) {
"use strict";
var privateStaticMethod() {
// ...
};
var privateStaticVariable = 10;
/**
* Builds a new MyClass
* @class A really cool class
* @property {Number} roProp A read-only property
* @property {Number} otherProp A property that doesn't change
* @memberOf Lens
*/
var MyClass = function() {
/** @alias Lens.MyClass.prototype */
var self = {};
var privateMember = 10;
var privateFunction = function() {};
/**
* My awesome public function.
*/
self.publicMethod = function() {};
/**
* My function that should only be called within Lens. This won't
* show up in the API documentation, but will show up in the
* internal documentation.
*
* @private
*/
self._internalMethod = function(){};
// this is how we define getters
Object.defineProperty(self, "roProp", {
get: function() { return privateMember * 10; }
});
// if your property doesn't change after initialization, just add
// it directly to self. It'll be read-only because self gets frozen.
self.otherProp = 20;
Object.freeze(self);
return self;
};
_.extend(MyClass, /** @lends Lens.MyClass */ {
/** An awesome class function */
publicClassFunction: function() {
// ...
}
});
Object.freeze(MyClass);
// Choose one:
// Lens._addMember(MyClass, "MyClass"); // for ARCore
// Lens._addMember(MyClass, "MyClass", Lens.LAF); // for LAF
// Lens._addMember(MyClass, "MyClass", Lens.Components); // for Componenets
return MyClass;
});
Documented Internal Classes
This is for classes whose constructor should not be made available to apps,
but should still show up in documentation. This is for data structures like Touch,
where apps shouldn't be creating their own objects, but need documentation on
the class because Lens will give developers pre-made instances. Note the
use of @privconstructor
define(["dep1", "dep2", "lib/underscore"], function(dep1, dep2, _) {
"use strict";
/**
* Builds a new MyClass
* @privconstructor
* @class A really cool class
* @name MyClass
*/
var MyClass = function() {
/** @alias MyClass.prototype */
var self = {};
var privateMember = 10;
var privateFunction = function() {};
/**
* My awesome public function.
*/
self.publicMethod = function() {};
Object.freeze(self);
return self;
};
return MyClass;
});
Internal Module
Modules that should not be part of the public Lens API.
/**
* My Internal Module!
* @namespace
* @name InternalModule
* @private
*/
define(["dep1", "dep2"], function(dep1, dep2) {
"use strict";
var privateFunction() {
// stuff
}
var InternalModule = /** @lends InternalModule */ {
/** Does cool stuff */
publicFunction: function() {
// stuff
}
}
return InternalModule;
});
Internal Classes
Classes that should not be part of the public Lens API.
define(["dep1", "dep2", "lib/underscore"], function(dep1, dep2, _) {
"use strict";
/**
* Builds a new MyClass
* @class A really cool class
* @name MyClass
* @private
*/
var MyClass = function() {
/** @alias MyClass.prototype */
var self = {};
var privateMember = 10;
var privateFunction = function() {};
/**
* My awesome public function.
*/
self.publicMethod = function() {};
Object.freeze(self);
return self;
};
return MyClass;
});
Coding Conventions
Indentation must be with 4 spaces.
The indentation style is Compact control readability style. This is essentially One True Brace with a newline before
else
:if(statement) { someCode() } else if(otherStatement) { someMoreCode(); } else { someOtherCode(); }
Lens defines only the global variable
Lens
. Everything else must be defined inside theLens
namespace. No changes should be made to the prototypes of built-in classes.Lens uses RequireJS modules. Lens' version of RequireJS is stored in
Lens.require
andLens.define
. No code should depend on any globals other thanLens
, rather, they should useLens.require
to load in e.g. jQuery. Code should also not assume that other Lens modules are loaded: if your code depends onLens.Dispatcher
, you must explicitly use aLens.require
call to load the dispatcher and then reference it via the argument passed to yourLens.require
callback.Lens modules should use underscores for the module/file name and be imported in UpperCamelCase, e.g.
Lens.require('foo_bar', function(FooBar){})
.Third-party libraries should be modified to act as RequireJS modules. These modifications should be clearly marked with
// LENS MODIFICATION
If a module can be run in a browser-only (no backend) mode, it should register a function to enable this mode by calling Lens.onDev();
Semicolons must be explicitly included at the end of lines. Do not rely on Javascript's automatic semicolon insertion.
All files must use strict mode. Start each
define
function with"use strict";
console.log
should never be used. Instead, requirecommon/util/log
and create a logger for your module.
Documentation Conventions
JSDoc3 is used for documentation. All exported methods and variables must have a doc comment.
Modules and functions that should be excluded from the API (but included in the internal docs) must be marked with @private. See Module Conventions for how to do this.
Acknowledgements
Lens LAF draws on existing work:
- Lato Font: http://www.google.com/webfonts/specimen/Lato
- Color Scheme & Inspiration: https://github.com/iurevych/Flat-UI
- Icons: http://kudakurage.com/ligature_symbols/
Reactivity and databases are taken from Meteor: