Mercurial > summit-idp
changeset 21:03c5651a371e
added banner image, uni-form, Attendees global
author | Atul Varma <avarma@mozilla.com> |
---|---|
date | Fri, 25 Jun 2010 16:00:15 -0700 |
parents | 3197696debbe |
children | da287d1b9405 |
files | static-files/banner.png static-files/default.uni-form.css static-files/index.html static-files/index.js static-files/uni-form.css static-files/uni-form.jquery.js summitidp/app.py tests/test_app.py |
diffstat | 8 files changed, 566 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/static-files/default.uni-form.css Fri Jun 25 16:00:15 2010 -0700 @@ -0,0 +1,153 @@ +/* ------------------------------------------------------------------------------ + + UNI-FORM DEFAULT by DRAGAN BABIC (v2) | Wed, 31 Mar 10 + + ------------------------------------------------------------------------------ + + Copyright (c) 2010, Dragan Babic + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ------------------------------------------------------------------------------ */ + +.uniForm{} + + .uniForm legend{ font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 0; } + + .uniForm .ctrlHolder{ padding: 1em; border-bottom: 1px solid #efefef; } + .uniForm .ctrlHolder.focused{ background: #fffcdf; } + + .uniForm .inlineLabels .noLabel{} + + .uniForm .buttonHolder{ background: #efefef; text-align: right; margin: 1.5em 0 0 0; padding: 1.5em; + /* CSS3 */ + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + -khtml-border-radius: 4px; + } + .uniForm .buttonHolder .primaryAction{ padding: 10px 22px; line-height: 1; background: #254a86; border: 1px solid #163362; font-size: 12px; font-weight: bold; color: #fff; + /* CSS3 */ + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + -khtml-border-radius: 4px; + box-shadow: 1px 1px 0 #fff; + -webkit-box-shadow: 1px 1px 0 #fff; + -moz-box-shadow: 1px 1px 0 #fff; + text-shadow: -1px -1px 0 rgba(0,0,0,.25); + } + .uniForm .buttonHolder .primaryAction:active{ position: relative; top: 1px; } + .uniForm .secondaryAction { text-align: left; } + .uniForm button.secondaryAction { background: transparent; border: none; color: #777; margin: 1.25em 0 0 0; padding: 0; } + + .uniForm .inlineLabels label em, + .uniForm .inlineLabels .label em{ font-style: normal; font-weight: bold; } + .uniForm label small{ font-size: .75em; color: #777; } + + .uniForm .textInput, + .uniForm textarea { padding: 4px 2px; border: 1px solid #aaa; background: #fff; } + .uniForm textarea { height: 12em; } + .uniForm select {} + .uniForm .fileUpload {} + + .uniForm ul{} + .uniForm li{} + .uniForm ul li label{ font-size: .85em; } + + .uniForm .small {} + .uniForm .medium{} + .uniForm .large {} /* Large is default and should match the value you set for .textInput, textarea or select */ + .uniForm .auto {} + .uniForm .small, + .uniForm .medium, + .uniForm .auto{} + + /* Get rid of the 'glow' effect in WebKit, optional */ + .uniForm .ctrlHolder .textInput:focus, + .uniForm .ctrlHolder textarea:focus{ outline: none; } + + .uniForm .formHint { font-size: .85em; color: #777; } + .uniForm .inlineLabels .formHint { padding-top: .5em; } + .uniForm .ctrlHolder.focused .formHint{ color: #333; } + +/* ----------------------------------------------------------------------------- */ +/* ############################### Messages #################################### */ +/* ----------------------------------------------------------------------------- */ + + /* Error message at the top of the form */ + .uniForm #errorMsg{ background: #ffdfdf; border: 1px solid #f3afb5; margin: 0 0 1.5em 0; padding: 0 1.5em; + /* CSS3 */ + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + -khtml-border-radius: 4px; + } + .uniForm #errorMsg h3{} /* Feel free to use a heading level suitable to your page structure */ + .uniForm #errorMsg ol{ margin: 0 0 1.5em 0; padding: 0; } + .uniForm #errorMsg ol li{ margin: 0 0 3px 1.5em; padding: 7px; background: #f6bec1; position: relative; font-size: .85em; + /* CSS3 */ + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + -khtml-border-radius: 4px; + } + + .uniForm .ctrlHolder.error, + .uniForm .ctrlHolder.focused.error{ background: #ffdfdf; border: 1px solid #f3afb5; + /* CSS3 */ + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + -khtml-border-radius: 4px; + } + .uniForm .ctrlHolder.error input.error, + .uniForm .ctrlHolder.error select.error, + .uniForm .ctrlHolder.error textarea.error{ color: #af4c4c; margin: 0 0 6px 0; padding: 4px; } + + /* Success messages at the top of the form */ + .uniForm #okMsg{ background: #c8ffbf; border: 1px solid #a2ef95; margin: 0 0 1.5em 0; padding: 0 1.5em; text-align: center; + /* CSS3 */ + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -o-border-radius: 4px; + -khtml-border-radius: 4px; + } + .uniForm #OKMsg p{ margin: 0; } + +/* ----------------------------------------------------------------------------- */ +/* ############################### Columns ##################################### */ +/* ----------------------------------------------------------------------------- */ + + .uniForm .col{} + .uniForm .col.first{} + .uniForm .col.last{} + .uniForm .col{ margin-bottom: 1.5em; } + /* Use .first and .last classes to control the layout/spacing of your columns */ + .uniForm .col.first{ width: 49%; float: left; clear: none; } + .uniForm .col.last { width: 49%; float: right; clear: none; margin-right: 0; } \ No newline at end of file
--- a/static-files/index.html Fri Jun 25 20:33:01 2010 +0000 +++ b/static-files/index.html Fri Jun 25 16:00:15 2010 -0700 @@ -1,59 +1,133 @@ <html> <head> <title>Mozilla Summit Identity Pal</title> + <link href="uni-form.css" media="all" rel="stylesheet"/> + <link href="default.uni-form.css" media="all" rel="stylesheet"/> <style> + #container { + width: 600px; + margin: 0 auto; + font-family: Helvetica Neue, Arial, sans-serif; + font-size: 9pt; + } + + a { + color: #6C2F70; + } + .screen { display: none; } + .success { + display: none; + color: green; + } + .error { display: none; - background: red; - color: white; + color: crimson; } .button { + -moz-border-radius: 4px; + background: #e0e0e0; + display: inline; + padding: 4px; cursor: pointer; - background: yellow; color: black; } + div.button:hover { + background: #b0b0b0; + } + .login-email { - font-family: monospace; - color: blue; + font-family: Monaco, monospace; + font-size: 8pt; + color: #6C2F70; } </style> </head> <body> +<div id="container"> <img id="banner" src="banner.png"> <div id="login" class="screen"> - <p>You don't seem to be logged in!</p> - <p>Enter your email address and press enter:</p> - <form> - <input type="text" id="email"> - </form> - <div class="error"> - <p>Fail! Maybe you entered an email address that isn't - registered for the summit, or maybe there's a bug - in this app.</p> - </div> + <p>Welcome to the Mozilla Summit Identity Pal!</p> + <p>Here you can enter information about yourself for sharing only + with other Summit-goers. It's a great way to find out who + will be at the Summit.</p> + <form action="#" class="uniForm"> + <fieldset> + <div class="ctrlHolder"> + <label for="Email Address">Email Address</label> + <input id="email" name="" value="" size="35" class="textInput" type="text"> + <p class="formHint">This should be the same email address you + receive your Summit Newsletter at.</p> + </div> + <div class="error"> + Alas, something didn't work. Maybe you entered an email address that isn't + registered for the Summit? + </div> + <div class="buttonHolder"><button type="submit" class="primaryAction">Submit</button></div> + </fieldset> + </form> </div> <div id="wait-for-verify" class="screen"> <p>An email was sent to you. Check your inbox and click the link in the email to log in.</p> + <form action="#" class="uniForm start-over"> + <fieldset> <div class="error"> - <p>Fail! Maybe the email was sent too long ago, or this - verification URL was already visited before, or there's - a bug in this app.</p> + Fail! Maybe the email was sent too long ago, or this + verification URL was already visited before? </div> - <div class="button start-over">Something messed up. Start - over!</div> + <div class="buttonHolder"><button type="submit" + class="primaryAction">Start Over</button></div> + </fieldset> + </form> </div> <div id="logged-in" class="screen"> <p>Hi! You are logged in as <span class="login-email"></span>.</p> - <div class="button start-over">Log Out</div> + <p>Please fill out some of the fields below. This information will + be made available only to other summit attendees and their cool + mashups and web apps.</p> + <form action="#" class="uniForm personal-info"> + <fieldset> + <div class="ctrlHolder"> + <label for="">Your Name</label> + <input id="name" name="" value="" size="35" class="textInput" type="text"> + <p class="formHint">What should people call you?</p> + </div> + + <div class="ctrlHolder"> + <label for="">Profile Image URL</label> + <input id="profile-image" name="" value="" size="35" class="textInput" type="text"> + <p class="formHint">If you have a picture of yourself somewhere, + paste in its URL here. It's expected to have square dimensions.</p> + </div> + + <div class="ctrlHolder"> + <label for="">Bugzilla Email</label> + <input id="bugzilla-email" name="" value="" size="35" class="textInput" type="text"> + <p class="formHint">If you use Bugzilla, enter your email here.</p> + </div> + + <div class="success"> + Great success! Your information has been updated. + </div> + + <div class="error"> + Fail! Maybe you're not connected to the internet? + </div> + + <div class="buttonHolder"><button type="submit" class="primaryAction">Submit</button></div> + </fieldset> + </form> +</div> </div> <script src="jquery-1.4.2.min.js"></script> +<script src="uni-form.jquery.js"></script> <script src="api.js"></script> <script src="index.js"></script> </body>
--- a/static-files/index.js Fri Jun 25 20:33:01 2010 +0000 +++ b/static-files/index.js Fri Jun 25 16:00:15 2010 -0700 @@ -25,42 +25,89 @@ observers: [] }; -var Api = { - postJSON: function Api_postJSON(path, obj, cb) { - var options = { - url: path, - type: "POST", - contentType: "application/json", - data: JSON.stringify(obj), - dataType: "json", - success: function(data) { - cb(true, data); - }, - error: function(req, textStatus, errorThrown) { - var data = null; - if (req.getResponseHeader("Content-Type") == "application/json") { - try { - data = JSON.parse(req.responseText); - } catch (e) {} - } - cb(false, data); - } - }; - return jQuery.ajax(options); - } -}; - ( - // This anonymous closure sets up the UI. + // Config initialization code. function(window) { function ensureStateIsValid() { if (!('state' in Config.value)) Config.setValue({state: "login"}); } + Config.observers.push(ensureStateIsValid); + + $(window).ready(ensureStateIsValid); + } +)(window); + +( + // Attendee initialization code. + function(window) { + var req; + + var Attendees = { + refresh: function refresh() { + if (req) + return; + var self = this; + if (Config.value.token) { + req = jQuery.getJSON( + "/profile", + {token: Config.value.token}, + function(data, textStatus) { + // TODO: Might need to add a failure callback too? + req = null; + if (textStatus == "success") { + self.value = data.contents; + self.observers.forEach(function(cb) { cb(); }); + } else { + // TODO: Raise an error? + } + }); + } + }, + value: null, + observers: [] + }; + + function refreshAttendees() { + if (Config.value.state == "logged-in" && !Attendees.users) + Attendees.refresh(); + } + + Config.observers.push(refreshAttendees); + $(window).ready(refreshAttendees); + + window.Attendees = Attendees; + } +)(window); + +jQuery.postJSON = function postJSON(path, obj, cb) { + var options = { + url: path, + type: "POST", + contentType: "application/json", + data: JSON.stringify(obj), + dataType: "json", + success: function(data) { + cb(true, data); + }, + error: function(req, textStatus, errorThrown) { + var data = null; + if (req.getResponseHeader("Content-Type") == "application/json") { + try { + data = JSON.parse(req.responseText); + } catch (e) {} + } + cb(false, data); + } + }; + return jQuery.ajax(options); +}; + +( + // This anonymous closure sets up the UI. + function(window) { function updateUI() { - ensureStateIsValid(); - $(".screen").hide(); $("#" + Config.value.state).show(); switch (Config.value.state) { @@ -74,6 +121,17 @@ } } + function fillUserInfo() { + var userInfo = Attendees.value[Config.value.userID]; + if (!userInfo) + userInfo = {}; + $("#name").val(userInfo.name || ""); + $("#profile-image").val(userInfo.profileImage || ""); + $("#bugzilla-email").val(userInfo.bugzillaEmail || ""); + } + + Attendees.observers.push(fillUserInfo); + function bindConfigToUI() { var lastChanged = Config.lastChanged; @@ -96,15 +154,17 @@ } function initUI() { - ensureStateIsValid(); - - $(".start-over").click(function() { Config.wipe(); }); + $(".start-over").submit( + function(event) { + event.preventDefault(); + Config.wipe(); + }); $("#login form").submit( function(event) { event.preventDefault(); $("#login .error").hide(); - Api.postJSON( + jQuery.postJSON( "/challenge/request", {email: $(this).find("#email").val() }, function(success, data) { @@ -116,11 +176,36 @@ }); }); + $("#logged-in form").submit( + function(event) { + event.preventDefault(); + $("#logged-in .success").hide(); + $("#logged-in .error").hide(); + + var contents = { + name: $("#name").val(), + profileImage: $("#profile-image").val(), + bugzillaEmail: $("#bugzilla-email").val() + }; + + jQuery.postJSON( + "/profile", + {token: Config.value.token, + contents: contents}, + function(success, data) { + if (success) { + $("#logged-in .success").slideDown(); + } else { + $("#logged-in .error").slideDown(); + } + }); + }); + var verify = window.location.hash.match(/#verify=(.+)/); if (verify && Config.value.state != "logged-in") { verify = verify[1]; Config.setValue({state: "wait-for-verify"}); - Api.postJSON( + jQuery.postJSON( "/challenge/respond", {token: verify}, function(success, data) { @@ -129,6 +214,7 @@ if (success) { Config.setValue({state: "logged-in", token: data.token, + userID: data.user_id, email: data.email}); } else { $("#wait-for-verify .error").slideDown(); @@ -145,6 +231,8 @@ ( // Set up the postMessage API. function(window) { + var attendeeCallbacks = []; + var myOrigin = window.location.protocol + "//" + window.location.host; var handlers = { getAllUsers: function(options, cb, origin) { @@ -160,18 +248,20 @@ return; } - jQuery.getJSON( - "/profile", - {token: Config.value.token}, - function(data, textStatus) { - if (textStatus == "success") - cb({users: data}); - else - cb({error: "an error occurred retrieving user data."}); - }); + if (Attendees.value) { + cb({users: Attendees.value}); + } else + attendeeCallbacks.push(cb); } }; var server = new Summit.Server(handlers); + + Attendees.observers.push( + function() { + var cbs = []; + attendeeCallbacks = []; + cbs.forEach(function(cb) { cb({users: Attendees.value}); }); + }); } )(window);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/static-files/uni-form.css Fri Jun 25 16:00:15 2010 -0700 @@ -0,0 +1,154 @@ +/* ------------------------------------------------------------------------------ + + Copyright (c) 2010, Dragan Babic + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ------------------------------------------------------------------------------ */ +/* ############################# GENERALS ################################### */ +/* ------------------------------------------------------------------------------ */ + +.uniForm{ margin: 0; padding: 0; position: relative; z-index: 1; } /* reset stuff */ + + /* Some generals and more resets */ + .uniForm fieldset{ border: none; margin: 0; padding: 0; } + .uniForm fieldset legend{ margin: 0; padding: 0; } + + /* This are the main units that contain form elements */ + .uniForm .ctrlHolder, + .uniForm .buttonHolder{ margin: 0; padding: 0; clear: both; } + + /* Clear all floats */ + .uniForm:after, + .uniForm .buttonHolder:after, + .uniForm .ctrlHolder:after, + .uniForm .ctrlHolder .multiField:after, + .uniForm .inlineLabel:after{ content: "."; display: block; height: 0; line-height: 0; font-size: 0; clear: both; min-height: 0; visibility: hidden; } + + .uniForm label, + .uniForm button{ cursor: pointer; } + +/* ------------------------------------------------------------------------------ */ +/* ########################## DEFAULT LAYOUT ################################ */ +/* ------------------------------------------------------------------------------ */ +/* Styles for form controls where labels are above the input elements */ +/* ------------------------------------------------------------------------------ */ + + .uniForm label, + .uniForm .label{ display: block; float: none; margin: 0 0 .5em 0; padding: 0; line-height: 100%; width: auto; } + + /* Float the input elements */ + .uniForm .textInput, + .uniForm .fileUpload, + .uniForm .selectInput, + .uniForm select, + .uniForm textarea{ float: left; width: 53%; margin: 0; } + + /* Postition the hints */ + .uniForm .formHint{ float: right; width: 43%; margin: 0; clear: none; } + + /* Position the elements inside combo boxes (multiple inputs/selects/checkboxes/radio buttons per unit) */ + .uniForm ul{ float: left; width: 53%; margin: 0; padding: 0; } + .uniForm ul li{ margin: 0 0 .5em 0; list-style: none; } + .uniForm ul li label{ margin: 0; float: none; display: block; overflow: visible; } + /* Alternate layout */ + .uniForm ul.alternate li{ float: left; width: 30%; margin-right: 3%; } + .uniForm ul.alternate li label{ float: none; display: block; width: 98%; } + .uniForm ul .textInput, + .uniForm ul .selectInput, + .uniForm ul select, + .uniForm ul.alternate .textInput, + .uniForm ul.alternate .selectInput, + .uniForm ul.alternate select{ width: 98%; margin-top: .5em; display: block; float: none; } + + /* Required fields asterisk styling */ + .uniForm label em, + .uniForm .label em{ float: left; width: 1em; margin: 0 0 0 -1em; } + +/* ------------------------------------------------------------------------------ */ +/* ######################### ALTERNATE LAYOUT ############################### */ +/* ------------------------------------------------------------------------------ */ +/* Styles for form controls where labels are in line with the input elements */ +/* Set the class of the parent (preferably to a fieldset) to .inlineLabels */ +/* ------------------------------------------------------------------------------ */ + + .uniForm .inlineLabels label, + .uniForm .inlineLabels .label{ float: left; margin: .3em 2% 0 0; padding: 0; line-height: 1; position: relative; width: 32%; } + + /* Float the input elements */ + .uniForm .inlineLabels .textInput, + .uniForm .inlineLabels .fileUpload, + .uniForm .inlineLabels .selectInput, + .uniForm .inlineLabels select, + .uniForm .inlineLabels textarea{ float: left; width: 64%; } + + /* Postition the hints */ + .uniForm .inlineLabels .formHint{ clear: both; float: none; width: auto; margin-left: 34%; position: static; } + + /* Position the elements inside combo boxes (multiple inputs/selects/checkboxes/radio buttons per unit) */ + .uniForm .inlineLabels ul{ float: left; width: 66%; } + .uniForm .inlineLabels ul li{ margin: .5em 0; } + .uniForm .inlineLabels ul li label{ float: none; display: block; width: 100%; } + /* Alternate layout */ + .uniForm .inlineLabels ul.alternate li{ margin-right: 3%; margin-top: .25em; } + .uniForm .inlineLabels ul li label .textInput, + .uniForm .inlineLabels ul li label textarea, + .uniForm .inlineLabels ul li label select{ float: none; display: block; width: 98%; } + + /* Required fields asterisk styling */ + .uniForm .inlineLabels label em, + .uniForm .inlineLabels .label em{ display: block; float: none; margin: 0; position: absolute; right: 0; } + +/* ----------------------------------------------------------------------------- */ +/* ########################### Additional Stuff ################################ */ +/* ----------------------------------------------------------------------------- */ + + /* Generals */ + .uniForm legend{ color: inherit; } + + .uniForm .secondaryAction{ float: left; } + + /* .inlineLabel is used for inputs within labels - checkboxes and radio buttons */ + .uniForm .inlineLabel input, + .uniForm .inlineLabels .inlineLabel input, + .uniForm .blockLabels .inlineLabel input, + /* class .inlineLabel is depreciated */ + .uniForm label input{ float: none; display: inline; margin: 0; padding: 0; border: none; } + + .uniForm .buttonHolder .inlineLabel, + .uniForm .buttonHolder label{ float: left; margin: .5em 0 0 0; width: auto; max-width: 60%; text-align: left; } + + /* When you don't want to use a label */ + .uniForm .inlineLabels .noLabel ul{ margin-left: 34%; /* Match to width of label + gap to field */ } + + /* Classes for control of the widths of the fields */ + .uniForm .small { width: 30% !important; } + .uniForm .medium{ width: 45% !important; } + .uniForm .large { } /* Large is default and should match the value you set for .textInput, textarea or select */ + .uniForm .auto { width: auto !important; } + .uniForm .small, + .uniForm .medium, + .uniForm .auto{ margin-right: 4px; } + +/* Columns */ +.uniForm .col{ float: left; } +.uniForm .col{ width: 50%; } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/static-files/uni-form.jquery.js Fri Jun 25 16:00:15 2010 -0700 @@ -0,0 +1,27 @@ +// Author: Ilija Studen for the purposes of UniāForm +// Modified by Aris Karageorgos to use the parents function + +jQuery.fn.uniform = function(settings) { + settings = jQuery.extend({ + valid_class : 'valid', + invalid_class : 'invalid', + focused_class : 'focused', + holder_class : 'ctrlHolder', + field_selector : 'input, select, textarea' + }, settings); + + return this.each(function() { + var form = jQuery(this); + // Select form fields and attach them higlighter functionality + form.find(settings.field_selector).focus(function() { + form.find('.' + settings.focused_class).removeClass(settings.focused_class); + $(this).parents().filter('.'+settings.holder_class+':first').addClass(settings.focused_class); + }).blur(function() { + form.find('.' + settings.focused_class).removeClass(settings.focused_class); + }); + }); +}; +// Auto set on page load... +$(document).ready(function() { + jQuery('form.uniForm').uniform(); +}); \ No newline at end of file
--- a/summitidp/app.py Fri Jun 25 20:33:01 2010 +0000 +++ b/summitidp/app.py Fri Jun 25 16:00:15 2010 -0700 @@ -162,12 +162,14 @@ ) email = chaltok['email'] self.challenge_tokens.revoke(body['token']) + user_id = self.emails.index(email) token = self.auth_tokens.create( email=email, - user_id=self.emails.index(email) + user_id=user_id ) return req.json_response('200 OK', {'token': token, + 'user_id': user_id, 'email': email}) return req.json_response('400 Bad Request', {'error': 'invalid body'})
--- a/tests/test_app.py Fri Jun 25 20:33:01 2010 +0000 +++ b/tests/test_app.py Fri Jun 25 16:00:15 2010 -0700 @@ -95,6 +95,7 @@ resp = post_json(server.respond_to_challenge_path, {'token': token}) assert resp.json == {'email': 'bob@foo.com', + 'user_id': 0, 'token': 'my auth token'} assert server.auth_tokens.get('my auth token') == { 'email': 'bob@foo.com', @@ -116,6 +117,7 @@ resp = post_json(server.respond_to_challenge_path, {'token': token}) assert resp.json == {'email': 'bob@foo.com', + 'user_id': 0, 'token': 'my auth token'} post_json(server.respond_to_challenge_path, {'token': token},