Account creation page
This commit is contained in:
Родитель
53b7caee3c
Коммит
a1c3331544
|
@ -1,20 +1,151 @@
|
|||
.gombot #outer-wrapper {
|
||||
border-top: 2px solid #fff;
|
||||
background: #f9f9f9 url(../img/sandstone/bg-labs.png) 0 0 repeat-x;
|
||||
background: rgb(246, 246, 246) url(../img/sandstone/bg-labs.png) 0 0 repeat-x;
|
||||
}
|
||||
|
||||
.gombot #main-feature {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 18px;
|
||||
}
|
||||
|
||||
.gombot button {
|
||||
height: 34px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.gombot .sign-up-input {
|
||||
margin-right: 10px;
|
||||
width: 18em;
|
||||
}
|
||||
|
||||
.gombot a,
|
||||
.gombot a:link,
|
||||
.gombot a:visited {
|
||||
color: #2983c8;
|
||||
}
|
||||
.gombot a:hover,
|
||||
.gombot a:active {
|
||||
color: #20679e;
|
||||
}
|
||||
|
||||
.gombot h2 img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.splash h1 {
|
||||
font-size: 52px;
|
||||
font-size: 63px;
|
||||
letter-spacing: -4px;
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.splash h2 {
|
||||
font-size: 37px;
|
||||
font-size: 40px;
|
||||
letter-spacing: -1px;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.create-account h2 {
|
||||
font-size: 3em;
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
#pin-info {
|
||||
display: none;
|
||||
}
|
||||
.show-info #pin-info {
|
||||
display: auto;
|
||||
}
|
||||
|
||||
.show-info .pin {
|
||||
background-color: #cbd4da;
|
||||
}
|
||||
|
||||
#sign-up {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 700px;
|
||||
text-align: middle;
|
||||
padding-bottom: 54px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
position: relative;
|
||||
float: left;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#splash-box {
|
||||
position: relative;
|
||||
background-color: rgb(190, 221, 227);
|
||||
background-image: url("/img/shadow.png");
|
||||
background-position: bottom left;
|
||||
background-repeat: no-repeat;
|
||||
display: inline;
|
||||
margin-left: -100px;
|
||||
margin-top: 66px;
|
||||
float: left;
|
||||
z-index: 1;
|
||||
padding: 25px 25px 67px 80px;
|
||||
}
|
||||
|
||||
.gombot #main-content {
|
||||
color: #222;
|
||||
font-family: 'Open Sans Light', sans-serif;
|
||||
}
|
||||
|
||||
.gombot label {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.gombot .create-account label {
|
||||
display: block;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
x-pin {
|
||||
font-size: 2.3em;
|
||||
height: 2.8em;
|
||||
}
|
||||
.gombot .pin input {
|
||||
width: 1.3em;
|
||||
}
|
||||
|
||||
.gombot .description {
|
||||
font-family: 'Open Sans Light', sans-serif;
|
||||
}
|
||||
|
||||
.gombot .description img {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
#splash-box .download {
|
||||
padding-left: 50px;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
#splash-box .download-button {
|
||||
position: relative;
|
||||
height: 52px;
|
||||
text-align: left;
|
||||
padding-left: 48px;
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
#splash-box a.download-button {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.download-button img {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
left: -24px;
|
||||
}
|
||||
|
||||
#splash-box .alts {
|
||||
display: block;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.firstrun .splash img.logo {
|
||||
float: left;
|
||||
}
|
||||
|
@ -30,3 +161,38 @@
|
|||
float: right;
|
||||
}
|
||||
|
||||
.create-account input[name="email"],
|
||||
.create-account input[name="password"],
|
||||
.create-account input[name="password_repeat"] {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.create-account form {
|
||||
float: left;
|
||||
width: 325px;
|
||||
}
|
||||
|
||||
.create-account p {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.create-account form .pin {
|
||||
padding: 10px 0 1px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.create-account form.show-info .pin {
|
||||
position: relative;
|
||||
background-color: #d7dce1;
|
||||
}
|
||||
|
||||
.create-account form.show-info #pin-info {
|
||||
display: block;
|
||||
position: absolute;
|
||||
background-color: #d7dce1;
|
||||
padding: 20px;
|
||||
left: 325px;
|
||||
top: 0px;
|
||||
width: 530px;
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 12 KiB |
|
@ -0,0 +1,770 @@
|
|||
(function(){
|
||||
|
||||
var doc = document,
|
||||
win = window,
|
||||
head = doc.getElementsByTagName('head')[0];
|
||||
|
||||
function nodeInserted(element, extendChildren){
|
||||
if (extendChildren && xtag.tagList.length && element.childNodes.length){
|
||||
xtag.query(element, xtag.tagList).forEach(function(element){
|
||||
nodeInserted(element);
|
||||
});
|
||||
}
|
||||
if (xtag.tagCheck(element)){
|
||||
xtag.extendElement(element);
|
||||
if (doc.documentElement.contains(element)){
|
||||
xtag.getOptions(element).onInsert.call(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Object containing various vendor specific details such as the CSS prefix
|
||||
* to use for the current browser.
|
||||
*
|
||||
* The following keys are set in the object:
|
||||
*
|
||||
* * css: the CSS prefix
|
||||
* * dom: the DOM prefix
|
||||
* * js: the Javascript prefix
|
||||
* * lowercase: a lower cased version of the browser prefix
|
||||
*
|
||||
* An example of this object on Chromium is the following
|
||||
*
|
||||
* {
|
||||
* css: "-webkit-"
|
||||
* dom: "WebKit"
|
||||
* js: "Webkit"
|
||||
* keyframes: true
|
||||
* lowercase: "webkit"
|
||||
* }
|
||||
*/
|
||||
var prefix = (function() {
|
||||
var styles = win.getComputedStyle(doc.documentElement, '');
|
||||
var pre = (
|
||||
Array.prototype.slice
|
||||
.call(styles)
|
||||
.join('')
|
||||
.match(/moz|webkit|ms/) || (styles.OLink===''&&['o'])
|
||||
)[0];
|
||||
|
||||
var dom = ('WebKit|Moz|MS|O')
|
||||
.match(new RegExp('(' + pre + ')', 'i'))[1];
|
||||
|
||||
return {
|
||||
dom: dom,
|
||||
lowercase: pre,
|
||||
css: '-' + pre + '-',
|
||||
js: pre[0].toUpperCase() + pre.substr(1)
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Stores the value of `current` in `source` using the key specified in
|
||||
* `key`.
|
||||
*
|
||||
* @param {object} source The object to store the value of the third
|
||||
* parameter.
|
||||
* @param {string} key The key under which to store the value.
|
||||
* @param {object|array} current The value to store in the object
|
||||
* specified in the `source` parameter.
|
||||
* @return {object}
|
||||
*/
|
||||
function mergeOne(source, key, current){
|
||||
switch (xtag.typeOf(current)){
|
||||
case 'object':
|
||||
if (xtag.typeOf(source[key]) == 'object'){
|
||||
xtag.merge(source[key], current);
|
||||
} else source[key] = xtag.clone(current);
|
||||
break;
|
||||
case 'array': source[key] = xtag.toArray(current); break;
|
||||
default: source[key] = current;
|
||||
}
|
||||
return source;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls the function in `fn` when the string in `value` contains an event
|
||||
* key code that matches a triggered event.
|
||||
*
|
||||
* @param {function} fn The function to call.
|
||||
* @param {string} value String containing the event key code.
|
||||
* @param {string} pseudo
|
||||
*/
|
||||
var keypseudo = {
|
||||
listener: function(pseudo, fn, args){
|
||||
if (!!~pseudo.value.match(/(\d+)/g).indexOf(String(args[0].keyCode))
|
||||
== (pseudo.name == 'keypass')){
|
||||
args.splice(args.length, 0, this);
|
||||
fn.apply(this, args);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var touchMap = {
|
||||
mouseenter: 'touchenter',
|
||||
mouseleave: 'touchleave',
|
||||
mousedown: 'touchstart',
|
||||
mousemove: 'touchmove',
|
||||
mouseup: 'touchend',
|
||||
click: 'touchend'
|
||||
};
|
||||
|
||||
var xtag = {
|
||||
tags: {},
|
||||
tagList: [],
|
||||
callbacks: {},
|
||||
prefix: prefix,
|
||||
anchor: doc.createElement('a'),
|
||||
mutation: win.MutationObserver ||
|
||||
win.WebKitMutationObserver ||
|
||||
win.MozMutationObserver,
|
||||
_matchSelector: document.documentElement.matchesSelector ||
|
||||
document.documentElement.mozMatchesSelector ||
|
||||
document.documentElement.webkitMatchesSelector,
|
||||
tagOptions: {
|
||||
content: '',
|
||||
mixins: [],
|
||||
events: {},
|
||||
methods: {},
|
||||
getters: {},
|
||||
setters: {},
|
||||
onCreate: function(){},
|
||||
onInsert: function(){}
|
||||
},
|
||||
|
||||
eventMap: {
|
||||
animationstart: [
|
||||
'animationstart',
|
||||
'oAnimationStart',
|
||||
'MSAnimationStart',
|
||||
'webkitAnimationStart'
|
||||
],
|
||||
transitionend: [
|
||||
'transitionend',
|
||||
'oTransitionEnd',
|
||||
'MSTransitionEnd',
|
||||
'webkitTransitionEnd'
|
||||
],
|
||||
tap: [ 'ontouchend' in doc ? 'touchend' : 'mouseup']
|
||||
},
|
||||
pseudos: {
|
||||
delegate: {
|
||||
listener: function(pseudo, fn, args){
|
||||
var target = xtag.query(this, pseudo.value).filter(function(node){
|
||||
return node == args[0].target ||
|
||||
node.contains ? node.contains(args[0].target) : false;
|
||||
})[0];
|
||||
return target ? fn.apply(target, args) : false;
|
||||
}
|
||||
},
|
||||
preventable: {
|
||||
listener: function(pseudo, fn, args){
|
||||
if (!args[0].defaultPrevented) fn.apply(this, args);
|
||||
}
|
||||
},
|
||||
attribute: {
|
||||
onAdd: function(pseudo){
|
||||
this.xtag.attributeSetters = this.xtag.attributeSetters || {};
|
||||
this.xtag.attributeSetters[pseudo.value] = pseudo.key.split(':')[0];
|
||||
},
|
||||
listener: function(pseudo, fn, args){
|
||||
fn.call(this, args[0]);
|
||||
this.setAttribute(pseudo.value, args[0], true);
|
||||
}
|
||||
},
|
||||
touch: {
|
||||
onAdd: function(pseudo, fn){
|
||||
this.addEventListener(touchMap[pseudo.key.split(':')[0]], fn, false);
|
||||
},
|
||||
listener: function(pseudo, fn, args){
|
||||
if (fn.touched && args[0].type.match('mouse')){
|
||||
fn.touched = false;
|
||||
} else {
|
||||
if (args[0].type.match('touch')) fn.touched = true;
|
||||
args.splice(args.length, 0, this);
|
||||
fn.apply(this, args);
|
||||
}
|
||||
},
|
||||
onRemove: function(pseudo, fn){
|
||||
this.removeEventListener(touchMap[pseudo.key.split(':')[0]], fn);
|
||||
}
|
||||
},
|
||||
keystop: keypseudo,
|
||||
keypass: keypseudo
|
||||
},
|
||||
|
||||
/**
|
||||
* Object containing various mixins that can be used when creating
|
||||
* custom tags.
|
||||
*
|
||||
* When registering a new tag you can specify these mixins as
|
||||
* following:
|
||||
*
|
||||
* xtag.register('tag-name', {
|
||||
* mixins: ['mixin1', 'mixin2', 'etc']
|
||||
* });
|
||||
*/
|
||||
mixins: {
|
||||
request: {
|
||||
onInsert: function(){
|
||||
this.src = this.getAttribute('src');
|
||||
},
|
||||
getters: {
|
||||
dataready: function(){
|
||||
return this.xtag.dataready;
|
||||
}
|
||||
},
|
||||
setters: {
|
||||
src: function(src){
|
||||
if (src){
|
||||
this.setAttribute('src', src);
|
||||
xtag.request(this, { url: src, method: 'GET' });
|
||||
}
|
||||
},
|
||||
dataready: function(fn){
|
||||
this.xtag.dataready = fn;
|
||||
if (this.xtag.request && this.xtag.request.readyState == 4){
|
||||
fn.call(this, this.xtag.request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a lowercased string containing the type of the object.
|
||||
*
|
||||
* @param {object} obj The object of which to retrieve the type.
|
||||
* @return {string}
|
||||
*/
|
||||
typeOf: function(obj) {
|
||||
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts the given object to an array.
|
||||
*
|
||||
* @param {object} obj The object to convert.
|
||||
* @return {array}
|
||||
*/
|
||||
toArray: function(obj){
|
||||
var sliced = Array.prototype.slice.call(obj, 0);
|
||||
return sliced.hasOwnProperty ? sliced : [obj];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a boolean that indicates if the element has the specified
|
||||
* class.
|
||||
*
|
||||
* @param {element} element The element for which to check the class.
|
||||
* @param {string} className The name of the class to check for.
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasClass: function(element, className){
|
||||
return !!~element.className.split(' ').indexOf(className);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the class to the specified element, existing classes will not
|
||||
* be overwritten.
|
||||
*
|
||||
* @param {element} element The element to add the class to.
|
||||
* @param {string} className The class to add.
|
||||
* @return {element}
|
||||
*/
|
||||
addClass: function(element, className){
|
||||
if (!xtag.hasClass(element, className)){
|
||||
var names = element.className.split(' ')
|
||||
.filter(function(item){ return item != "" });
|
||||
names.push(className);
|
||||
element.className = names.join(' ');
|
||||
}
|
||||
return element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the given class from the element.
|
||||
*
|
||||
* @param {element} element The element from which to remove the class.
|
||||
* @param {string} className The class to remove.
|
||||
* @return {element}
|
||||
*/
|
||||
removeClass: function(element, className){
|
||||
var names = element.className.split(' ')
|
||||
.filter(function(item){ return item != "" }),
|
||||
idx = names.indexOf(className);
|
||||
if (idx>=0) names.splice(idx,1);
|
||||
element.className = names.join(' ');
|
||||
return element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the class on the element. If the class is added it's
|
||||
* removed, if not it will be added instead.
|
||||
*
|
||||
* @param {element} element The element for which to toggle the class.
|
||||
* @param {string} className The class to toggle.
|
||||
* @return {element}
|
||||
*/
|
||||
toggleClass: function(element, className){
|
||||
return !xtag.hasClass(element, className) ?
|
||||
xtag.addClass(element,className) : xtag.removeClass(element, className);
|
||||
},
|
||||
|
||||
/**
|
||||
* matchSelector helper
|
||||
*
|
||||
* @param {element} element The element to test.
|
||||
* @param {string} selector The CSS selector to use for the test.
|
||||
* @return {boolean}
|
||||
*/
|
||||
matchSelector: function(element, selector){
|
||||
return xtag._matchSelector.call(element, selector);
|
||||
},
|
||||
|
||||
/**
|
||||
* Queries a set of child elements using a CSS selector.
|
||||
*
|
||||
* @param {element} element The element to query.
|
||||
* @param {string} selector The CSS selector to use for the query.
|
||||
* @return {array}
|
||||
*/
|
||||
query: function(element, selector){
|
||||
return xtag.toArray(element.querySelectorAll(selector));
|
||||
},
|
||||
|
||||
queryChildren: function(element, selector){
|
||||
var result = null,
|
||||
id = 'x-' + new Date().getTime(),
|
||||
attr = '[xtag-temp-id="' + id + '"] > ',
|
||||
selector = attr + (selector + '').replace(',', ',' + attr, 'g');
|
||||
element.setAttribute('xtag-temp-id', id);
|
||||
result = element.parentNode.querySelectorAll(selector);
|
||||
element.removeAttribute('xtag-temp-id');
|
||||
return xtag.toArray(result);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function that can be used to define a property on an element.
|
||||
*
|
||||
* @param {element} element The element on which to define the
|
||||
* property.
|
||||
* @param {string} property The property to define.
|
||||
* @param {string} accessor The accessor name.
|
||||
* @param {string} value The value of the property.
|
||||
*/
|
||||
defineProperty: function(element, property, accessor, value){
|
||||
return doc.documentElement.__defineGetter__ ?
|
||||
function(element, property, accessor, value){
|
||||
element['__define' + accessor[0].toUpperCase() +
|
||||
'etter__'](property, value);
|
||||
} :
|
||||
function(element, property, accessor, value){
|
||||
var obj = { configurable: true };
|
||||
obj[accessor] = value;
|
||||
Object.defineProperty(element, property, obj);
|
||||
};
|
||||
}(),
|
||||
|
||||
/**
|
||||
* Creates a new function and sets the prototype to the specified
|
||||
* object.
|
||||
*
|
||||
* @param {object} obj The object to use as the prototype for the new
|
||||
* function.
|
||||
* @return {function}
|
||||
*/
|
||||
clone: function(obj) {
|
||||
var F = function(){};
|
||||
F.prototype = obj;
|
||||
return new F();
|
||||
},
|
||||
|
||||
merge: function(source, k, v){
|
||||
if (xtag.typeOf(k) == 'string') return mergeOne(source, k, v);
|
||||
for (var i = 1, l = arguments.length; i < l; i++){
|
||||
var object = arguments[i];
|
||||
for (var key in object) mergeOne(source, key, object[key]);
|
||||
}
|
||||
return source;
|
||||
},
|
||||
|
||||
wrap: function(original, fn){
|
||||
return function(){
|
||||
var args = xtag.toArray(arguments);
|
||||
original.apply(this, args);
|
||||
fn.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
skipTransition: function(element, fn, bind){
|
||||
var duration = prefix.js + 'TransitionDuration';
|
||||
element.style[duration] = '0.001s';
|
||||
fn.call(bind);
|
||||
xtag.addEvent(element, 'transitionend', function(){
|
||||
element.style[duration] = '';
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the specified element is an x-tag element or a regular
|
||||
* element.
|
||||
*
|
||||
* @param {element} element The element to check.
|
||||
* @return {boolean}
|
||||
*/
|
||||
tagCheck: function(element){
|
||||
return element.nodeName ? xtag.tags[element.nodeName.toLowerCase()] : false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object containing the options of an element.
|
||||
*
|
||||
* @param {element} element The element for which to retrieve the
|
||||
* options.
|
||||
* @return {object}
|
||||
*/
|
||||
getOptions: function(element){
|
||||
return xtag.tagCheck(element) || xtag.tagOptions;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a new x-tag object.
|
||||
*
|
||||
* @param {string} tag The name of the tag.
|
||||
* @param {object} options An object containing custom configuration
|
||||
* options to use for the tag.
|
||||
*/
|
||||
register: function(tag, options){
|
||||
xtag.tagList.push(tag);
|
||||
xtag.tags[tag] = xtag.merge({ tagName: tag }, xtag.tagOptions,
|
||||
xtag.applyMixins(options || {}));
|
||||
if (xtag.domready) xtag.query(doc, tag).forEach(function(element){
|
||||
nodeInserted(element);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Extends an element by adding various x-tag related getters, setters
|
||||
* and other properties to it.
|
||||
*
|
||||
* @param {element} element The element to extend.
|
||||
*/
|
||||
extendElement: function(element){
|
||||
if (!element.xtag && xtag.tagCheck(element)){
|
||||
element.xtag = {}; // used as general storage
|
||||
var options = xtag.getOptions(element);
|
||||
for (var z in options.methods){
|
||||
xtag.bindMethod(element, z, options.methods[z]);
|
||||
}
|
||||
for (var z in options.setters){
|
||||
xtag.applyAccessor(element, z, 'set', options.setters[z]);
|
||||
}
|
||||
for (var z in options.getters){
|
||||
xtag.applyAccessor(element, z, 'get', options.getters[z]);
|
||||
}
|
||||
xtag.addEvents(element, options.events);
|
||||
if (options.content) element.innerHTML = options.content;
|
||||
options.onCreate.call(element);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper method to ensure x-tags that are inserted via innerHTML
|
||||
* are inflated.
|
||||
*
|
||||
* @param {element} element The element.
|
||||
* @param {html} element The html to insert.
|
||||
*/
|
||||
innerHTML: function(element, html){
|
||||
element.innerHTML = html;
|
||||
if (xtag.observer){
|
||||
xtag.parseMutations(xtag.observer.takeRecords(), nodeInserted);
|
||||
}
|
||||
else {
|
||||
nodeInserted(element);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Binds a method to the specified element under the given key.
|
||||
*
|
||||
* @param {element} element The element to bind the method to.
|
||||
* @param {string} key The name of the key in which to store the
|
||||
* method.
|
||||
* @param {function} method The method/function to bind to the element.
|
||||
*/
|
||||
bindMethod: function(element, key, method){
|
||||
element[key] = function(){
|
||||
return method.apply(element, xtag.toArray(arguments))
|
||||
};
|
||||
},
|
||||
|
||||
applyMixins: function(options){
|
||||
if (options.mixins){
|
||||
options.mixins.forEach(function(name){
|
||||
var mixin = xtag.mixins[name];
|
||||
for (var z in mixin) {
|
||||
switch (xtag.typeOf(mixin[z])){
|
||||
case 'function':
|
||||
options[z] = options[z] ?
|
||||
xtag.wrap(options[z], mixin[z]) : mixin[z];
|
||||
break;
|
||||
case 'object':
|
||||
options[z] = xtag.merge({}, mixin[z], options[z]);
|
||||
break;
|
||||
default:
|
||||
options[z] = mixin[z];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return options;
|
||||
},
|
||||
|
||||
applyAccessor: function(element, key, accessor, fn){
|
||||
xtag.defineProperty(element,
|
||||
key.split(':')[0], accessor, xtag.applyPseudos(element, key, fn));
|
||||
},
|
||||
|
||||
applyPseudos: function(element, key, fn){
|
||||
var action = fn, onAdd = {};
|
||||
if (key.match(':')){
|
||||
|
||||
var split = key.match(/(\w+(?:\([^\)]+\))?)/g);
|
||||
for (var i = split.length - 1; i > 0; i--) {
|
||||
|
||||
split[i].replace(/(\w*)(?:\(([^\)]*)\))?/, function(match, name, value){
|
||||
var lastPseudo = action,
|
||||
pseudo = xtag.pseudos[name],
|
||||
split = {
|
||||
key: key,
|
||||
name: name,
|
||||
value: value
|
||||
};
|
||||
if (!pseudo) throw "pseudo not found: " + name;
|
||||
if (pseudo.onAdd) onAdd[name] = split;
|
||||
action = function(e){
|
||||
if (e) e.customElement = element;
|
||||
var args = xtag.toArray(arguments);
|
||||
args[1] = element;
|
||||
return pseudo.listener.apply(this,
|
||||
[split, lastPseudo, args]);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
for (var z in onAdd){
|
||||
xtag.pseudos[z].onAdd.call(element, onAdd[z], action);
|
||||
}
|
||||
}
|
||||
return action;
|
||||
},
|
||||
|
||||
removePseudos: function(element, key, fn){
|
||||
if (key.match(':')){
|
||||
key.replace(/:(\w*)(?:\(([^\)]*)\))?/g, function(match, name, value){
|
||||
var lastPseudo = action,
|
||||
pseudo = xtag.pseudos[name],
|
||||
split = {
|
||||
key: key,
|
||||
name: name,
|
||||
value: value
|
||||
};
|
||||
if (pseudo.onRemove) pseudo.onRemove.call(element, split, lastPseudo);
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
request: function(element, options){
|
||||
xtag.clearRequest(element);
|
||||
var last = element.xtag.request || {};
|
||||
element.xtag.request = options;
|
||||
var request = element.xtag.request,
|
||||
callbackKey = element.getAttribute('data-callback-key') ||
|
||||
'callback' + '=xtag.callbacks.';
|
||||
if (xtag.fireEvent(element, 'beforerequest') === false) return false;
|
||||
if (last.url && !options.update &&
|
||||
last.url.replace(new RegExp('\&?\(' + callbackKey + 'x[0-9]+)'), '') ==
|
||||
element.xtag.request.url){
|
||||
element.xtag.request = last;
|
||||
return false;
|
||||
}
|
||||
element.setAttribute('src', element.xtag.request.url);
|
||||
xtag.anchor.href = options.url;
|
||||
if (xtag.anchor.hostname == win.location.hostname) {
|
||||
request = xtag.merge(new XMLHttpRequest(), request);
|
||||
request.onreadystatechange = function(){
|
||||
element.setAttribute('data-readystate', request.readyState);
|
||||
if (request.readyState == 4 && request.status < 400){
|
||||
xtag.requestCallback(element, request);
|
||||
}
|
||||
};
|
||||
['error', 'abort', 'load'].forEach(function(type){
|
||||
request['on' + type] = function(event){
|
||||
event.request = request;
|
||||
xtag.fireEvent(element, type, event);
|
||||
}
|
||||
});
|
||||
request.open(request.method , request.url, true);
|
||||
request.setRequestHeader('Content-Type',
|
||||
'application/x-www-form-urlencoded');
|
||||
request.send();
|
||||
}
|
||||
else {
|
||||
var callbackID = request.callbackID = 'x' + new Date().getTime();
|
||||
element.setAttribute('data-readystate', request.readyState = 0);
|
||||
xtag.callbacks[callbackID] = function(data){
|
||||
request.status = 200;
|
||||
request.readyState = 4;
|
||||
request.responseText = data;
|
||||
xtag.requestCallback(element, request);
|
||||
delete xtag.callbacks[callbackID];
|
||||
xtag.clearRequest(element);
|
||||
}
|
||||
request.script = doc.createElement('script');
|
||||
request.script.type = 'text/javascript';
|
||||
request.script.src = options.url = options.url +
|
||||
(~options.url.indexOf('?') ? '&' : '?') + callbackKey + callbackID;
|
||||
request.script.onerror = function(error){
|
||||
element.setAttribute('data-readystate', request.readyState = 4);
|
||||
element.setAttribute('data-requeststatus', request.status = 400);
|
||||
xtag.fireEvent(element, 'error', error);
|
||||
}
|
||||
head.appendChild(request.script);
|
||||
}
|
||||
element.xtag.request = request;
|
||||
},
|
||||
|
||||
requestCallback: function(element, request){
|
||||
if (request != element.xtag.request) return xtag;
|
||||
element.setAttribute('data-readystate', request.readyState);
|
||||
element.setAttribute('data-requeststatus', request.status);
|
||||
xtag.fireEvent(element, 'dataready', { request: request });
|
||||
if (element.dataready) element.dataready.call(element, request);
|
||||
},
|
||||
|
||||
clearRequest: function(element){
|
||||
var req = element.xtag.request;
|
||||
if (!req) return xtag;
|
||||
if (req.script && ~xtag.toArray(head.children).indexOf(req.script)) {
|
||||
head.removeChild(req.script);
|
||||
}
|
||||
else if (req.abort) req.abort();
|
||||
},
|
||||
|
||||
addEvent: function(element, type, fn){
|
||||
var eventKey = type.split(':')[0],
|
||||
eventMap = xtag.eventMap[eventKey] || [eventKey];
|
||||
var wrapped = xtag.applyPseudos(element, type, fn);
|
||||
eventMap.forEach(function(name){
|
||||
element.addEventListener(name,
|
||||
wrapped, !!~['focus', 'blur'].indexOf(name));
|
||||
});
|
||||
return wrapped;
|
||||
},
|
||||
|
||||
addEvents: function(element, events){
|
||||
for (var z in events) xtag.addEvent(element, z, events[z]);
|
||||
},
|
||||
|
||||
removeEvent: function(element, type, fn){
|
||||
var eventKey = type.split(':')[0],
|
||||
eventMap = xtag.eventMap[eventKey] || [eventKey];
|
||||
eventMap.forEach(function(name){
|
||||
element.removeEventListener(name, fn);
|
||||
});
|
||||
},
|
||||
|
||||
fireEvent: function(element, type, data, options){
|
||||
var options = options || {},
|
||||
event = doc.createEvent('Event');
|
||||
event.initEvent(type, 'bubbles' in options ? options.bubbles : true, 'cancelable' in options ? options.cancelable : true);
|
||||
element.dispatchEvent(xtag.merge(event, data));
|
||||
},
|
||||
|
||||
parseMutations: function(mutations, fn) {
|
||||
var added = [];
|
||||
mutations.forEach(function(record){
|
||||
var nodes = record.addedNodes, length = nodes.length;
|
||||
for (i = 0; i < length && added.indexOf(nodes[i]) == -1; i++){
|
||||
added.push(nodes[i]);
|
||||
fn(nodes[i], true);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
observe: function(element, fn){
|
||||
if (xtag.mutation){
|
||||
var observer = new xtag.mutation(function(mutations) {
|
||||
xtag.parseMutations(mutations, fn);
|
||||
});
|
||||
observer.observe(element, {
|
||||
subtree: true,
|
||||
childList: true,
|
||||
attributes: !true,
|
||||
characterData: false
|
||||
});
|
||||
xtag.observer = observer;
|
||||
}
|
||||
else element.addEventListener('DOMNodeInserted', function(event){
|
||||
fn(event.target, true);
|
||||
}, false);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
var setAttribute = HTMLElement.prototype.setAttribute;
|
||||
(win.HTMLUnknownElement || HTMLElement).prototype.setAttribute = function(attr, value, setter){
|
||||
if (!setter && this.xtag && this.xtag.attributeSetters){
|
||||
this[this.xtag.attributeSetters[attr]] = value;
|
||||
}
|
||||
setAttribute.call(this, attr, value);
|
||||
};
|
||||
|
||||
var createElement = doc.createElement;
|
||||
doc.createElement = function(tag){
|
||||
var element = createElement.call(this, tag);
|
||||
xtag.extendElement(element);
|
||||
return element;
|
||||
};
|
||||
|
||||
function init(){
|
||||
xtag.observe(doc.documentElement, nodeInserted);
|
||||
if (xtag.tagList.length){
|
||||
xtag.query(doc, xtag.tagList).forEach(function(element){
|
||||
nodeInserted(element);
|
||||
});
|
||||
}
|
||||
xtag.domready = true;
|
||||
xtag.fireEvent(doc, 'DOMComponentsLoaded');
|
||||
xtag.fireEvent(doc, '__DOMComponentsLoaded__');
|
||||
}
|
||||
|
||||
|
||||
if (doc.readyState == 'complete'){
|
||||
init();
|
||||
}
|
||||
else if (doc.readyState == 'interactive'){
|
||||
doc.addEventListener('readystatechange', function(e){
|
||||
init();
|
||||
});
|
||||
}
|
||||
else {
|
||||
doc.addEventListener('DOMContentLoaded', function(event){
|
||||
init();
|
||||
}, false);
|
||||
}
|
||||
|
||||
if (typeof define == 'function' && define.amd) {
|
||||
define(xtag);
|
||||
}
|
||||
else {
|
||||
win.xtag = xtag;
|
||||
}
|
||||
|
||||
})();
|
|
@ -0,0 +1,7 @@
|
|||
$(function () {
|
||||
|
||||
$('#pin-info-link').click(function (ev) {
|
||||
$('#account-form').toggleClass('show-info');
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
x-pin {
|
||||
display: inline-block;
|
||||
}
|
||||
x-pin > div.x-pin-fields {
|
||||
height: inherit;
|
||||
font-size: inherit;
|
||||
|
||||
display: -webkit-flex;
|
||||
-webkit-flex-direction: row;
|
||||
|
||||
display: -moz-flex;
|
||||
-moz-flex-direction: row;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
x-pin > div.x-pin-fields > input {
|
||||
font-size: inherit;
|
||||
height: auto;
|
||||
margin: 2px 0;
|
||||
text-align: center;
|
||||
|
||||
-webkit-flex: 1 1 auto;
|
||||
-moz-flex: 1 1 auto;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
x-pin > div.x-pin-fields > input + input {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
(function(window, document, undefined) {
|
||||
|
||||
function refreshElements() {
|
||||
this.xtag.fields.innerHTML = '';
|
||||
var pin = this;
|
||||
for (var i = 0; i < this.size; i++) {
|
||||
var elem = document.createElement('input');
|
||||
elem.setAttribute('type', 'password');
|
||||
elem.setAttribute('size', '1');
|
||||
elem.setAttribute('maxlength', '1');
|
||||
elem.setAttribute('data-index', i);
|
||||
elem.onchange = function (e){
|
||||
var val = [].splice.call(pin.value, 0);
|
||||
val[this.dataset.index] = this.value;
|
||||
pin.xtag.input.value = val.join('');
|
||||
};
|
||||
elem.oninput = function (e){
|
||||
var fields = pin.xtag.fields.childNodes;
|
||||
var i = parseInt(this.dataset.index, 10) + 1;
|
||||
if (this.value.length && i < pin.size) {
|
||||
fields[i].focus();
|
||||
}
|
||||
};
|
||||
if (this.value[i]) elem.value = this.value[i];
|
||||
this.xtag.fields.appendChild(elem);
|
||||
}
|
||||
xtag.fireEvent(this, 'changed', { value: this.value });
|
||||
}
|
||||
|
||||
xtag.register('x-pin', {
|
||||
onCreate: function() {
|
||||
this.innerHTML = '<input type="hidden" /><div class="x-pin-fields"></div>';
|
||||
this.xtag.input = xtag.query(this, 'input')[0];
|
||||
this.xtag.input.value = '';
|
||||
this.xtag.fields = xtag.query(this, '.x-pin-fields')[0];
|
||||
refreshElements.call(this);
|
||||
},
|
||||
getters: {
|
||||
size: function() {
|
||||
return parseInt(this.getAttribute('size'), 10);
|
||||
},
|
||||
value: function() {
|
||||
return this.xtag.input.value;
|
||||
},
|
||||
name: function() {
|
||||
return this.xtag.input.getAttribute('name');
|
||||
}
|
||||
},
|
||||
setters: {
|
||||
size: function(value) {
|
||||
this.setAttibute('size', value);
|
||||
refreshElements.call(this);
|
||||
},
|
||||
value: function(value) {
|
||||
if (typeof value !== 'undefined') {
|
||||
this.xtag.input.setAttribute('value', value);
|
||||
refreshElements.call(this);
|
||||
}
|
||||
},
|
||||
'name:attribute(name)': function(value) {
|
||||
this.xtag.input.setAttribute('name', value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})(window, window.document);
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "Date Time Picker",
|
||||
"tagName": "x-pin",
|
||||
"version": "0.0.1",
|
||||
"author": "Zachary Carter",
|
||||
"description": "Enter PINs",
|
||||
"images": [],
|
||||
"categories": ["input"],
|
||||
"demo": "demo",
|
||||
"compatibility": {
|
||||
"firefox": 5,
|
||||
"chrome": 4,
|
||||
"ie": 9,
|
||||
"opera": 12,
|
||||
"android": 2.1,
|
||||
"ios": 4
|
||||
},
|
||||
"documentation":{
|
||||
"description": "Creates a special PIN entry field with multiple input boxes",
|
||||
"attributes": {
|
||||
"size": "The number of digits in the PIN."
|
||||
"name": "The name of the field"
|
||||
},
|
||||
"events": {
|
||||
"change": "Fired each time the input value is changed"
|
||||
},
|
||||
"methods": {
|
||||
},
|
||||
"getters": {
|
||||
"value": "Returns the value of the PIN",
|
||||
"size": "Returns the number of digits in the entry field",
|
||||
"name": "Returns the input name"
|
||||
},
|
||||
"setters": {
|
||||
"value": "Sets the value of the PIN",
|
||||
"size": "Sets the number of digits to be entered",
|
||||
"name": "Sets the input name and the controls name"
|
||||
}
|
||||
},
|
||||
"dependencies":[]
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- If you are using sandstone for a static website, you can safely delete this file -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Mozilla — Gombot — mozilla.org</title>
|
||||
|
||||
<link rel="shortcut icon" href="../common/img/favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="../common/style/tabzilla.css" media="screen" />
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<script src="../common/js/libs/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../common/css/sandstone-resp.css" media="screen" />
|
||||
<link rel="stylesheet" type="text/css" href="../common/css/gombot.css" media="screen" />
|
||||
<link rel="stylesheet" type="text/css" href="../common/x-tags/pin/pin.css" media="screen" />
|
||||
|
||||
|
||||
<script src="../common/js/libs/x-tag.js"></script>
|
||||
<script src="../common/x-tags/pin/pin.js"></script>
|
||||
|
||||
</head>
|
||||
<!-- The four different themes of sandstone are, stone, sand, sky, space. Replace the class on the
|
||||
body tag below, with the theme you wish to use for your project -->
|
||||
<body id="sandstone" class="sand gombot firstrun">
|
||||
<div id="outer-wrapper">
|
||||
<div id="wrapper">
|
||||
|
||||
<header id="masthead">
|
||||
<a href="http://www.mozilla.org/" id="tabzilla">Mozilla</a>
|
||||
<nav id="nav-main" role="menubar">
|
||||
<span class="toggle" role="button" aria-controls="nav-main-menu" tabindex="0">Menu</span>
|
||||
<ul role="menu" id="nav-main-menu">
|
||||
<li><a class="" href="https://mozillalabs.com/en-US/">Home</a></li>
|
||||
<li><a class="" href="https://mozillalabs.com/en-US/about/">About</a></li>
|
||||
<li><a class="current" href="https://mozillalabs.com/en-US/projects/">Projects</a></li>
|
||||
<li><a href="http://blog.mozilla.com/labs/">Blog</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
<h2><a href="http://mozillalabs.com/"><img src="../common/img/sandstone/header-mozilla-labs.png" alt="mozilla"></a></h2>
|
||||
|
||||
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<div id="main-content">
|
||||
<div class="row create-account">
|
||||
<!--<img class="logo" src="img/mascot-gombot.png">-->
|
||||
<h2><img src="../common/img/gombot-logo-92x92.png" /> Create a Gombot account</h2>
|
||||
<form action="http://dev.tobmog.org/account" method="post" id="account-form">
|
||||
|
||||
<p>
|
||||
Already have an account? <a href="#">Sign in</a>
|
||||
</p>
|
||||
|
||||
<div class="pin">
|
||||
<p>
|
||||
<label>Choose a PIN. <a href="#" id="pin-info-link"> What is the PIN for?</a></label>
|
||||
|
||||
<x-pin name="pin" size="4"></x-pin>
|
||||
|
||||
<span id="pin-info">Protect your critical passwords with a PIN code – just like your bank card. Choose whichsites to lock with a PIN and use the same PIN no matter how many sites you save.</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label>Repeat PIN</label>
|
||||
<x-pin name="pin-repeat" size="4"></x-pin>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<label>email address</label>
|
||||
<input type="text" name="email" />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label>choose master password</label>
|
||||
<input type="password" name="password" />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label>repeat password</label>
|
||||
<input type="password" name="password_repeat" />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button class="button-blue">Sign up »</button><br />
|
||||
<small>Already have an account? <a href="#">Sign in</a></small>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer id="colophon">
|
||||
<div class="row">
|
||||
<div class="footer-logo">
|
||||
<a href="http://mozilla.org"><img src="../common/img/sandstone/footer-mozilla.png" alt="mozilla"></a>
|
||||
</div>
|
||||
|
||||
<div class="footer-license">
|
||||
<p>Portions of this content are ©1998–2012 by individual mozilla.org contributors. Content available under a <a href="http://www.mozilla.org/foundation/licensing/website-content.html">Creative Commons license</a>.</p>
|
||||
<p><a href="http://mozilla.org/b/en-US/contribute/page/">Contribute to this page</a></p>
|
||||
</div>
|
||||
<ul class="footer-nav">
|
||||
<li><a href="http://mozilla.org/about/contact.html#map-mountain_view">Contact Us</a></li>
|
||||
<li><a href="http://mozilla.org/privacy-policy.html">Privacy Policy</a></li>
|
||||
<li><a href="http://mozilla.org/about/legal.html">Legal Notices</a></li>
|
||||
<li><a href="http://mozilla.org/legal/fraud-report/index.html">Report Trademark Abuse</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="footer-nav">
|
||||
<li><a href="http://twitter.com/firefox">Twitter</a></li>
|
||||
<li><a href="http://facebook.com/Firefox">Facebook</a></li>
|
||||
<li><a href="https://affiliates.mozilla.org/">Firefox Affiliates</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
<script src="../common/js/tabzilla.js"></script>
|
||||
<script src="../common/js/libs/jquery-1.7.1.min.js"></script>
|
||||
<script src="../common/js/site.js"></script>
|
||||
<script src="../common/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
Загрузка…
Ссылка в новой задаче