Merge branch 'master' into gh-pages

This commit is contained in:
Rufus Pollock 2012-03-29 09:50:52 +01:00
commit b6142f44ce
18 changed files with 1833 additions and 754 deletions

View File

@ -27,6 +27,10 @@
margin-bottom: auto;
}
.recline-query-editor .add-on {
float: left;
}
.header .recline-query-editor .text-query input {
float: left;
}

View File

@ -10,7 +10,7 @@
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="../vendor/bootstrap/2.0.0/css/bootstrap.css">
<link rel="stylesheet" href="../vendor/bootstrap/2.0.2/css/bootstrap.css">
<link rel="stylesheet" href="../css/data-explorer.css">
<link rel="stylesheet" href="../css/graph-flot.css">
<link rel="stylesheet" href="style/demo.css">
@ -21,7 +21,7 @@
<script type="text/javascript" src="../vendor/jquery-ui-1.8.14.custom.min.js"></script>
<script type="text/javascript" src="../vendor/jquery.flot-0.7.js"></script>
<script type="text/javascript" src="../vendor/jquery.mustache.js"></script>
<script type="text/javascript" src="../vendor/bootstrap/2.0.0/bootstrap.js"></script>
<script type="text/javascript" src="../vendor/bootstrap/2.0.2/bootstrap.js"></script>
<script type="text/javascript" src="../recline.js"></script>
<script type="text/javascript" src="js/app.js"></script>

View File

@ -10,11 +10,11 @@
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="../vendor/bootstrap/2.0.0/css/bootstrap.css">
<link rel="stylesheet" href="../vendor/bootstrap/2.0.2/css/bootstrap.css">
<link rel="stylesheet" href="../css/data-explorer.css">
<link rel="stylesheet" href="../css/graph-flot.css">
<link rel="stylesheet" href="style/demo.css">
<link rel="stylesheet" href="../vendor/bootstrap/2.0.0/css/bootstrap-responsive.css">
<link rel="stylesheet" href="../vendor/bootstrap/2.0.2/css/bootstrap-responsive.css">
<!-- 3rd party libraries -->
<script type="text/javascript" src="../vendor/jquery-1.7.1.js"></script>
@ -23,7 +23,7 @@
<script type="text/javascript" src="../vendor/jquery-ui-1.8.14.custom.min.js"></script>
<script type="text/javascript" src="../vendor/jquery.flot-0.7.js"></script>
<script type="text/javascript" src="../vendor/jquery.mustache.js"></script>
<script type="text/javascript" src="../vendor/bootstrap/2.0.0/bootstrap.js"></script>
<script type="text/javascript" src="../vendor/bootstrap/2.0.2/bootstrap.js"></script>
<!-- recline library -->
<!-- in normal use would just the single recline.js library file. However, for testing it
@ -36,6 +36,7 @@
<script type="text/javascript" src="../src/backend/dataproxy.js"></script>
<script type="text/javascript" src="../src/backend/elasticsearch.js"></script>
<script type="text/javascript" src="../src/backend/gdocs.js"></script>
<script type="text/javascript" src="../src/backend/localcsv.js"></script>
<script type="text/javascript" src="../src/view.js"></script>
<script type="text/javascript" src="../src/view-grid.js"></script>
<script type="text/javascript" src="../src/view-flot-graph.js"></script>
@ -53,20 +54,74 @@
<li><a href="../#docs">Documentation</a></li>
</ul>
<ul class="nav pull-right">
<li class="dropdown">
<a data-toggle="dropdown" class="dropdown-toggle">
Import <b class="caret"></b></a>
<ul class="dropdown-menu js-import">
<li>
<a data-toggle="modal" href=".js-import-dialog-url">Import from URL</a>
</li>
<li>
<a data-toggle="modal" href=".js-import-dialog-file">Import from File</a>
</li>
</ul>
</li>
<li><a class="set-read-only" title="Put into read-only mode">Read-only</a></li>
</ul>
<form class="webstore-load pull-right navbar-search" title="Update from the specified webstore dataset">
<input type="text" name="source" size="50" />
<select name="backend_type">
<option value="elasticsearch">ElasticSearch</option>
<option value="dataproxy">DataProxy</option>
<option value="gdocs">Google Spreadsheet (JSON API)</option>
</select>
</form>
</div>
</div>
</div>
<div class="modal fade in js-import-dialog-url" style="display: none;">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Import from URL</h3>
</div>
<div class="modal-body">
<form class="js-import-url form-horizontal">
<div class="control-group">
<label class="control-label">URL</label>
<div class="controls">
<input type="text" name="source" class="input-xlarge" />
</div>
</div>
<div class="control-group">
<label class="control-label">Type of data</label>
<div class="controls">
<select name="backend_type">
<option value="elasticsearch">ElasticSearch</option>
<option value="dataproxy">CSV or Excel</option>
<option value="gdocs">Google Spreadsheet</option>
</select>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Import &raquo;</button>
</div>
</form>
</div>
</div>
<div class="modal fade in js-import-dialog-file" style="display: none;">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Import from File</h3>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label">File</label>
<div class="controls">
<input type="file" name="source" />
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Import &raquo;</button>
</div>
</form>
</div>
</div>
<div class="container-fluid">
<div class="content">
<div class="data-explorer-here"></div>

View File

@ -101,9 +101,10 @@ function localDataset() {
function setupLoader(callback) {
// pre-populate webstore load form with an example url
var demoUrl = 'http://thedatahub.org/api/data/b9aae52b-b082-4159-b46f-7bb9c158d013';
$('form.webstore-load input[name="source"]').val(demoUrl);
$('form.webstore-load').submit(function(e) {
$('form.js-import-url input[name="source"]').val(demoUrl);
$('form.js-import-url').submit(function(e) {
e.preventDefault();
$('.modal.js-import-dialog-url').modal('hide');
var $form = $(e.target);
var source = $form.find('input[name="source"]').val();
var type = $form.find('select[name="backend_type"]').val();
@ -116,5 +117,16 @@ function setupLoader(callback) {
);
callback(dataset);
});
$('.js-import-dialog-file form').submit(function(e) {
e.preventDefault();
var $form = $(e.target);
$('.modal.js-import-dialog-file').modal('hide');
var $file = $form.find('input[type="file"]')[0];
var file = $file.files[0];
recline.Backend.loadFromCSVFile(file, function(dataset) {
callback(dataset)
});
});
}

View File

@ -547,7 +547,7 @@ my.FlotGraph = Backbone.View.extend({
points: { show: true },
lines: { show: true }
},
grid: { hoverable: true, clickable: true },
grid: { hoverable: true, clickable: true }
}
, bars: {
series: {
@ -872,7 +872,7 @@ my.DataGrid = Backbone.View.extend({
<th class="column-header {{#hidden}}hidden{{/hidden}}" data-field="{{id}}"> \
<div class="btn-group column-header-menu"> \
<a class="btn dropdown-toggle" data-toggle="dropdown"><i class="icon-cog"></i><span class="caret"></span></a> \
<ul class="dropdown-menu data-table-menu"> \
<ul class="dropdown-menu data-table-menu pull-right"> \
<li class="write-op"><a data-action="bulkEdit" href="JavaScript:void(0);">Transform...</a></li> \
<li class="write-op"><a data-action="deleteColumn" href="JavaScript:void(0);">Delete this column</a></li> \
<li><a data-action="sortAsc" href="JavaScript:void(0);">Sort ascending</a></li> \
@ -909,7 +909,7 @@ my.DataGrid = Backbone.View.extend({
var newView = new my.DataGridRow({
model: doc,
el: tr,
fields: self.fields,
fields: self.fields
},
self.options
);

162
src/backend/localcsv.js Normal file
View File

@ -0,0 +1,162 @@
this.recline = this.recline || {};
this.recline.Backend = this.recline.Backend || {};
(function($, my) {
my.loadFromCSVFile = function(file, callback) {
var metadata = {
id: file.name,
file: file
};
var reader = new FileReader();
// TODO
reader.onload = function(e) {
var dataset = my.csvToDataset(e.target.result);
callback(dataset);
};
reader.onerror = function (e) {
alert('Failed to load file. Code: ' + e.target.error.code);
}
reader.readAsText(file);
};
my.csvToDataset = function(csvString) {
var out = my.parseCSV(csvString);
fields = _.map(out[0], function(cell) {
return { id: cell, label: cell };
});
var data = _.map(out.slice(1), function(row) {
var _doc = {};
_.each(out[0], function(fieldId, idx) {
_doc[fieldId] = row[idx];
});
return _doc;
});
var dataset = recline.Backend.createDataset(data, fields);
return dataset;
}
// Converts a Comma Separated Values string into an array of arrays.
// Each line in the CSV becomes an array.
//
// Empty fields are converted to nulls and non-quoted numbers are converted to integers or floats.
//
// @return The CSV parsed as an array
// @type Array
//
// @param {String} s The string to convert
// @param {Boolean} [trm=false] If set to True leading and trailing whitespace is stripped off of each non-quoted field as it is imported
//
// Heavily based on uselesscode's JS CSV parser (MIT Licensed):
// thttp://www.uselesscode.org/javascript/csv/
my.parseCSV= function(s, trm) {
// Get rid of any trailing \n
s = chomp(s);
var cur = '', // The character we are currently processing.
inQuote = false,
fieldQuoted = false,
field = '', // Buffer for building up the current field
row = [],
out = [],
i,
processField;
processField = function (field) {
if (fieldQuoted !== true) {
// If field is empty set to null
if (field === '') {
field = null;
// If the field was not quoted and we are trimming fields, trim it
} else if (trm === true) {
field = trim(field);
}
// Convert unquoted numbers to their appropriate types
if (rxIsInt.test(field)) {
field = parseInt(field, 10);
} else if (rxIsFloat.test(field)) {
field = parseFloat(field, 10);
}
}
return field;
};
for (i = 0; i < s.length; i += 1) {
cur = s.charAt(i);
// If we are at a EOF or EOR
if (inQuote === false && (cur === ',' || cur === "\n")) {
field = processField(field);
// Add the current field to the current row
row.push(field);
// If this is EOR append row to output and flush row
if (cur === "\n") {
out.push(row);
row = [];
}
// Flush the field buffer
field = '';
fieldQuoted = false;
} else {
// If it's not a ", add it to the field buffer
if (cur !== '"') {
field += cur;
} else {
if (!inQuote) {
// We are not in a quote, start a quote
inQuote = true;
fieldQuoted = true;
} else {
// Next char is ", this is an escaped "
if (s.charAt(i + 1) === '"') {
field += '"';
// Skip the next char
i += 1;
} else {
// It's not escaping, so end quote
inQuote = false;
}
}
}
}
}
// Add the last field
field = processField(field);
row.push(field);
out.push(row);
return out;
};
var rxIsInt = /^\d+$/,
rxIsFloat = /^\d*\.\d+$|^\d+\.\d*$/,
// If a string has leading or trailing space,
// contains a comma double quote or a newline
// it needs to be quoted in CSV output
rxNeedsQuoting = /^\s|\s$|,|"|\n/,
trim = (function () {
// Fx 3.1 has a native trim function, it's about 10x faster, use it if it exists
if (String.prototype.trim) {
return function (s) {
return s.trim();
};
} else {
return function (s) {
return s.replace(/^\s*/, '').replace(/\s*$/, '');
};
}
}());
function chomp(s) {
if (s.charAt(s.length - 1) !== "\n") {
// Does not end with \n, just return string
return s;
} else {
// Remove the \n
return s.substring(0, s.length - 1);
}
}
}(jQuery, this.recline.Backend));

View File

@ -2,6 +2,45 @@ this.recline = this.recline || {};
this.recline.Backend = this.recline.Backend || {};
(function($, my) {
// ## createDataset
//
// Convenience function to create a simple 'in-memory' dataset in one step.
//
// @param data: list of hashes for each document/row in the data ({key:
// value, key: value})
// @param fields: (optional) list of field hashes (each hash defining a hash
// as per recline.Model.Field). If fields not specified they will be taken
// from the data.
// @param metadata: (optional) dataset metadata - see recline.Model.Dataset.
// If not defined (or id not provided) id will be autogenerated.
my.createDataset = function(data, fields, metadata) {
if (!metadata) {
var metadata = {};
}
if (!metadata.id) {
metadata.id = String(Math.floor(Math.random() * 100000000) + 1);
}
var backend = recline.Model.backends['memory'];
var datasetInfo = {
documents: data,
metadata: metadata
};
if (fields) {
datasetInfo.fields = fields;
} else {
if (data) {
datasetInfo.fields = _.map(data[0], function(cell) {
return {id: cell};
});
}
}
backend.addDataset(datasetInfo);
var dataset = new recline.Model.Dataset({id: metadata.id}, 'memory');
dataset.fetch();
return dataset;
};
// ## Memory Backend - uses in-memory data
//
// To use it you should provide in your constructor data:

View File

@ -201,7 +201,7 @@ my.FlotGraph = Backbone.View.extend({
points: { show: true },
lines: { show: true }
},
grid: { hoverable: true, clickable: true },
grid: { hoverable: true, clickable: true }
}
, bars: {
series: {

View File

@ -174,7 +174,7 @@ my.DataGrid = Backbone.View.extend({
<th class="column-header {{#hidden}}hidden{{/hidden}}" data-field="{{id}}"> \
<div class="btn-group column-header-menu"> \
<a class="btn dropdown-toggle" data-toggle="dropdown"><i class="icon-cog"></i><span class="caret"></span></a> \
<ul class="dropdown-menu data-table-menu"> \
<ul class="dropdown-menu data-table-menu pull-right"> \
<li class="write-op"><a data-action="bulkEdit" href="JavaScript:void(0);">Transform...</a></li> \
<li class="write-op"><a data-action="deleteColumn" href="JavaScript:void(0);">Delete this column</a></li> \
<li><a data-action="sortAsc" href="JavaScript:void(0);">Sort ascending</a></li> \
@ -211,7 +211,7 @@ my.DataGrid = Backbone.View.extend({
var newView = new my.DataGridRow({
model: doc,
el: tr,
fields: self.fields,
fields: self.fields
},
self.options
);

View File

@ -0,0 +1,32 @@
(function ($) {
module("Backend Local CSV");
test("parseCSV", function() {
var csv = '"Jones, Jay",10\n' +
'"Xyz ""ABC"" O\'Brien",11:35\n' +
'"Other, AN",12:35\n';
var array = recline.Backend.parseCSV(csv);
var exp = [
['Jones, Jay', 10],
['Xyz "ABC" O\'Brien', '11:35' ],
['Other, AN', '12:35' ]
];
deepEqual(exp, array);
var csv = '"Jones, Jay", 10\n' +
'"Xyz ""ABC"" O\'Brien", 11:35\n' +
'"Other, AN", 12:35\n';
var array = recline.Backend.parseCSV(csv, true);
deepEqual(exp, array);
var csv = 'Name, Value\n' +
'"Jones, Jay", 10\n' +
'"Xyz ""ABC"" O\'Brien", 11:35\n' +
'"Other, AN", 12:35\n';
var dataset = recline.Backend.csvToDataset(csv);
dataset.query();
equal(dataset.currentDocuments.length, 3);
});
})(this.jQuery);

View File

@ -25,6 +25,17 @@ function makeBackendDataset() {
return dataset;
}
test('Memory Backend: createDataset', function () {
var dataset = recline.Backend.createDataset(memoryData.documents, memoryData.fields, memoryData.metadata);
equal(memoryData.metadata.id, dataset.id);
});
test('Memory Backend: createDataset 2', function () {
var dataset = recline.Backend.createDataset(memoryData.documents);
dataset.query();
equal(memoryData.documents.length, dataset.currentDocuments.length);
});
test('Memory Backend: basics', function () {
var dataset = makeBackendDataset();
expect(3);

View File

@ -20,12 +20,13 @@
<script type="text/javascript" src="model.test.js"></script>
<script type="text/javascript" src="../src/backend/base.js"></script>
<script type="text/javascript" src="../src/backend/memory.js"></script>
<script type="text/javascript" src="../src/backend/webstore.js"></script>
<script type="text/javascript" src="../src/backend/dataproxy.js"></script>
<script type="text/javascript" src="../src/backend/gdocs.js"></script>
<script type="text/javascript" src="../src/backend/elasticsearch.js"></script>
<script type="text/javascript" src="../src/backend/localcsv.js"></script>
<script type="text/javascript" src="backend.test.js"></script>
<script type="text/javascript" src="backend.elasticsearch.test.js"></script>
<script type="text/javascript" src="backend.localcsv.test.js"></script>
<script type="text/javascript" src="../src/view.js"></script>
<script type="text/javascript" src="../src/view-grid.js"></script>
<script type="text/javascript" src="../src/view-transform-dialog.js"></script>

View File

@ -18,6 +18,21 @@ test('Field: basics', function () {
},
'should throw an error if not passed in a hash with id'
);
// toJSON
var field = new recline.Model.Field({
id: 'x',
label: 'My label'
});
var out = field.toJSON();
equal('My label', out.label);
var fieldList = new recline.Model.FieldList([
{id: 'xx', label: 'XX'},
{id: 'yy', label: 'YY'}
]);
var out = fieldList.toJSON();
equal('XX', out[0].label);
});
test('Dataset', function () {

View File

@ -1,5 +1,5 @@
/* ===================================================
* bootstrap-transition.js v2.0.0
* bootstrap-transition.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#transitions
* ===================================================
* Copyright 2012 Twitter, Inc.
@ -47,10 +47,9 @@
})()
})
}( window.jQuery )
/* ==========================================================
* bootstrap-alert.js v2.0.0
}( window.jQuery );/* ==========================================================
* bootstrap-alert.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#alerts
* ==========================================================
* Copyright 2012 Twitter, Inc.
@ -102,11 +101,14 @@
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
$parent.removeClass('in')
$parent
.trigger('close')
.removeClass('in')
function removeElement() {
$parent.remove()
$parent.trigger('closed')
$parent
.trigger('closed')
.remove()
}
$.support.transition && $parent.hasClass('fade') ?
@ -139,9 +141,8 @@
$('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
})
}( window.jQuery )
/* ============================================================
* bootstrap-button.js v2.0.0
}( window.jQuery );/* ============================================================
* bootstrap-button.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#buttons
* ============================================================
* Copyright 2012 Twitter, Inc.
@ -233,13 +234,14 @@
$(function () {
$('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
$(e.target).button('toggle')
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
$btn.button('toggle')
})
})
}( window.jQuery )
/* ==========================================================
* bootstrap-carousel.js v2.0.0
}( window.jQuery );/* ==========================================================
* bootstrap-carousel.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#carousel
* ==========================================================
* Copyright 2012 Twitter, Inc.
@ -269,6 +271,9 @@
this.$element = $(element)
this.options = $.extend({}, $.fn.carousel.defaults, options)
this.options.slide && this.slide(this.options.slide)
this.options.pause == 'hover' && this.$element
.on('mouseenter', $.proxy(this.pause, this))
.on('mouseleave', $.proxy(this.cycle, this))
}
Carousel.prototype = {
@ -301,6 +306,7 @@
, pause: function () {
clearInterval(this.interval)
this.interval = null
return this
}
@ -328,6 +334,8 @@
$next = $next.length ? $next : this.$element.find('.item')[fallback]()
if ($next.hasClass('active')) return
if (!$.support.transition && this.$element.hasClass('slide')) {
this.$element.trigger('slide')
$active.removeClass('active')
@ -373,6 +381,7 @@
$.fn.carousel.defaults = {
interval: 5000
, pause: 'hover'
}
$.fn.carousel.Constructor = Carousel
@ -391,9 +400,8 @@
})
})
}( window.jQuery )
/* =============================================================
* bootstrap-collapse.js v2.0.0
}( window.jQuery );/* =============================================================
* bootstrap-collapse.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#collapse
* =============================================================
* Copyright 2012 Twitter, Inc.
@ -468,7 +476,9 @@
[dimension](size || 'auto')
[0].offsetWidth
this.$element.addClass('collapse')
this.$element[size ? 'addClass' : 'removeClass']('collapse')
return this
}
, transition: function ( method, startEvent, completeEvent ) {
@ -527,9 +537,8 @@
})
})
}( window.jQuery )
/* ============================================================
* bootstrap-dropdown.js v2.0.0
}( window.jQuery );/* ============================================================
* bootstrap-dropdown.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#dropdowns
* ============================================================
* Copyright 2012 Twitter, Inc.
@ -619,9 +628,8 @@
$('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
})
}( window.jQuery )
/* =========================================================
* bootstrap-modal.js v2.0.0
}( window.jQuery );/* =========================================================
* bootstrap-modal.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#modals
* =========================================================
* Copyright 2012 Twitter, Inc.
@ -648,7 +656,7 @@
* ====================== */
var Modal = function ( content, options ) {
this.options = $.extend({}, $.fn.modal.defaults, options)
this.options = options
this.$element = $(content)
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
}
@ -799,16 +807,17 @@
return this.each(function () {
var $this = $(this)
, data = $this.data('modal')
, options = typeof option == 'object' && option
, options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('modal', (data = new Modal(this, options)))
if (typeof option == 'string') data[option]()
else data.show()
else if (options.show) data.show()
})
}
$.fn.modal.defaults = {
backdrop: true
, keyboard: true
, show: true
}
$.fn.modal.Constructor = Modal
@ -828,9 +837,8 @@
})
})
}( window.jQuery )
/* ===========================================================
* bootstrap-tooltip.js v2.0.0
}( window.jQuery );/* ===========================================================
* bootstrap-tooltip.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#tooltips
* Inspired by the original jQuery.tipsy by Jason Frame
* ===========================================================
@ -1037,7 +1045,7 @@
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
title = title.toString().replace(/(^\s*|\s*$)/, "")
title = (title || '').toString().replace(/(^\s*|\s*$)/, "")
return title
}
@ -1098,9 +1106,8 @@
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
}
}( window.jQuery )
/* ===========================================================
* bootstrap-popover.js v2.0.0
}( window.jQuery );/* ===========================================================
* bootstrap-popover.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#popovers
* ===========================================================
* Copyright 2012 Twitter, Inc.
@ -1193,9 +1200,8 @@
, template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
})
}( window.jQuery )
/* =============================================================
* bootstrap-scrollspy.js v2.0.0
}( window.jQuery );/* =============================================================
* bootstrap-scrollspy.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#scrollspy
* =============================================================
* Copyright 2012 Twitter, Inc.
@ -1318,9 +1324,8 @@
})
})
}( window.jQuery )
/* ========================================================
* bootstrap-tab.js v2.0.0
}( window.jQuery );/* ========================================================
* bootstrap-tab.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#tabs
* ========================================================
* Copyright 2012 Twitter, Inc.
@ -1448,9 +1453,8 @@
})
})
}( window.jQuery )
/* =============================================================
* bootstrap-typeahead.js v2.0.0
}( window.jQuery );/* =============================================================
* bootstrap-typeahead.js v2.0.2
* http://twitter.github.com/bootstrap/javascript.html#typeahead
* =============================================================
* Copyright 2012 Twitter, Inc.
@ -1491,6 +1495,7 @@
, select: function () {
var val = this.$menu.find('.active').attr('data-value')
this.$element.val(val)
this.$element.change();
return this.hide()
}
@ -1616,9 +1621,6 @@
}
, keyup: function (e) {
e.stopPropagation()
e.preventDefault()
switch(e.keyCode) {
case 40: // down arrow
case 38: // up arrow
@ -1631,6 +1633,7 @@
break
case 27: // escape
if (!this.shown) return
this.hide()
break
@ -1638,10 +1641,11 @@
this.lookup()
}
e.stopPropagation()
e.preventDefault()
}
, keypress: function (e) {
e.stopPropagation()
if (!this.shown) return
switch(e.keyCode) {
@ -1661,12 +1665,12 @@
this.next()
break
}
e.stopPropagation()
}
, blur: function (e) {
var that = this
e.stopPropagation()
e.preventDefault()
setTimeout(function () { that.hide() }, 150)
}
@ -1719,4 +1723,4 @@
})
})
}( window.jQuery )
}( window.jQuery );

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap Responsive v2.0.0
* Bootstrap Responsive v2.0.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
@ -7,10 +7,85 @@
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
.clearfix {
*zoom: 1;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
.hide-text {
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
}
.input-block-level {
display: block;
width: 100%;
min-height: 28px;
/* Make inputs at least the height of their button counterpart */
/* Makes inputs behave like true block-level elements */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.hidden {
display: none;
visibility: hidden;
}
.visible-phone {
display: none;
}
.visible-tablet {
display: none;
}
.visible-desktop {
display: block;
}
.hidden-phone {
display: block;
}
.hidden-tablet {
display: block;
}
.hidden-desktop {
display: none;
}
@media (max-width: 767px) {
.visible-phone {
display: block;
}
.hidden-phone {
display: none;
}
.hidden-desktop {
display: block;
}
.visible-desktop {
display: none;
}
}
@media (min-width: 768px) and (max-width: 979px) {
.visible-tablet {
display: block;
}
.hidden-tablet {
display: none;
}
.hidden-desktop {
display: block;
}
.visible-desktop {
display: none;
}
}
@media (max-width: 480px) {
.nav-collapse {
-webkit-transform: translate3d(0, 0, 0);
@ -19,34 +94,8 @@
display: block;
line-height: 18px;
}
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {
display: block;
width: 100%;
height: 28px;
/* Make inputs at least the height of their button counterpart */
/* Makes inputs behave like true block-level elements */
-webkit-box-sizing: border-box;
/* Older Webkit */
-moz-box-sizing: border-box;
/* Older FF */
-ms-box-sizing: border-box;
/* IE8 */
box-sizing: border-box;
/* CSS3 spec*/
}
.input-prepend input[class*="span"], .input-append input[class*="span"] {
width: auto;
}
input[type="checkbox"], input[type="radio"] {
input[type="checkbox"],
input[type="radio"] {
border: 1px solid #ccc;
}
.form-horizontal .control-group > label {
@ -84,10 +133,17 @@
position: static;
}
}
@media (max-width: 768px) {
@media (max-width: 767px) {
body {
padding-left: 20px;
padding-right: 20px;
}
.navbar-fixed-top {
margin-left: -20px;
margin-right: -20px;
}
.container {
width: auto;
padding: 0 20px;
}
.row-fluid {
width: 100%;
@ -95,19 +151,44 @@
.row {
margin-left: 0;
}
.row > [class*="span"], .row-fluid > [class*="span"] {
.row > [class*="span"],
.row-fluid > [class*="span"] {
float: none;
display: block;
width: auto;
margin: 0;
}
.thumbnails [class*="span"] {
width: auto;
}
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {
display: block;
width: 100%;
min-height: 28px;
/* Make inputs at least the height of their button counterpart */
/* Makes inputs behave like true block-level elements */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.input-prepend input[class*="span"],
.input-append input[class*="span"] {
width: auto;
}
}
@media (min-width: 768px) and (max-width: 980px) {
@media (min-width: 768px) and (max-width: 979px) {
.row {
margin-left: -20px;
*zoom: 1;
}
.row:before, .row:after {
.row:before,
.row:after {
display: table;
content: "";
}
@ -118,80 +199,89 @@
float: left;
margin-left: 20px;
}
.span1 {
width: 42px;
.container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 724px;
}
.span2 {
width: 104px;
}
.span3 {
width: 166px;
}
.span4 {
width: 228px;
}
.span5 {
width: 290px;
}
.span6 {
width: 352px;
}
.span7 {
width: 414px;
}
.span8 {
width: 476px;
}
.span9 {
width: 538px;
}
.span10 {
width: 600px;
.span12 {
width: 724px;
}
.span11 {
width: 662px;
}
.span12, .container {
width: 724px;
.span10 {
width: 600px;
}
.offset1 {
margin-left: 82px;
.span9 {
width: 538px;
}
.offset2 {
margin-left: 144px;
.span8 {
width: 476px;
}
.offset3 {
margin-left: 206px;
.span7 {
width: 414px;
}
.offset4 {
margin-left: 268px;
.span6 {
width: 352px;
}
.offset5 {
margin-left: 330px;
.span5 {
width: 290px;
}
.offset6 {
margin-left: 392px;
.span4 {
width: 228px;
}
.offset7 {
margin-left: 454px;
.span3 {
width: 166px;
}
.offset8 {
margin-left: 516px;
.span2 {
width: 104px;
}
.offset9 {
margin-left: 578px;
.span1 {
width: 42px;
}
.offset12 {
margin-left: 764px;
}
.offset11 {
margin-left: 702px;
}
.offset10 {
margin-left: 640px;
}
.offset11 {
margin-left: 702px;
.offset9 {
margin-left: 578px;
}
.offset8 {
margin-left: 516px;
}
.offset7 {
margin-left: 454px;
}
.offset6 {
margin-left: 392px;
}
.offset5 {
margin-left: 330px;
}
.offset4 {
margin-left: 268px;
}
.offset3 {
margin-left: 206px;
}
.offset2 {
margin-left: 144px;
}
.offset1 {
margin-left: 82px;
}
.row-fluid {
width: 100%;
*zoom: 1;
}
.row-fluid:before, .row-fluid:after {
.row-fluid:before,
.row-fluid:after {
display: table;
content: "";
}
@ -205,80 +295,85 @@
.row-fluid > [class*="span"]:first-child {
margin-left: 0;
}
.row-fluid .span1 {
width: 5.801104972%;
}
.row-fluid .span2 {
width: 14.364640883%;
}
.row-fluid .span3 {
width: 22.928176794%;
}
.row-fluid .span4 {
width: 31.491712705%;
}
.row-fluid .span5 {
width: 40.055248616%;
}
.row-fluid .span6 {
width: 48.618784527%;
}
.row-fluid .span7 {
width: 57.182320438000005%;
}
.row-fluid .span8 {
width: 65.74585634900001%;
}
.row-fluid .span9 {
width: 74.30939226%;
}
.row-fluid .span10 {
width: 82.87292817100001%;
}
.row-fluid .span11 {
width: 91.436464082%;
}
.row-fluid .span12 {
.row-fluid > .span12 {
width: 99.999999993%;
}
input.span1, textarea.span1, .uneditable-input.span1 {
width: 32px;
.row-fluid > .span11 {
width: 91.436464082%;
}
input.span2, textarea.span2, .uneditable-input.span2 {
width: 94px;
.row-fluid > .span10 {
width: 82.87292817100001%;
}
input.span3, textarea.span3, .uneditable-input.span3 {
width: 156px;
.row-fluid > .span9 {
width: 74.30939226%;
}
input.span4, textarea.span4, .uneditable-input.span4 {
width: 218px;
.row-fluid > .span8 {
width: 65.74585634900001%;
}
input.span5, textarea.span5, .uneditable-input.span5 {
width: 280px;
.row-fluid > .span7 {
width: 57.182320438000005%;
}
input.span6, textarea.span6, .uneditable-input.span6 {
width: 342px;
.row-fluid > .span6 {
width: 48.618784527%;
}
input.span7, textarea.span7, .uneditable-input.span7 {
width: 404px;
.row-fluid > .span5 {
width: 40.055248616%;
}
input.span8, textarea.span8, .uneditable-input.span8 {
width: 466px;
.row-fluid > .span4 {
width: 31.491712705%;
}
input.span9, textarea.span9, .uneditable-input.span9 {
width: 528px;
.row-fluid > .span3 {
width: 22.928176794%;
}
input.span10, textarea.span10, .uneditable-input.span10 {
width: 590px;
.row-fluid > .span2 {
width: 14.364640883%;
}
input.span11, textarea.span11, .uneditable-input.span11 {
width: 652px;
.row-fluid > .span1 {
width: 5.801104972%;
}
input,
textarea,
.uneditable-input {
margin-left: 0;
}
input.span12, textarea.span12, .uneditable-input.span12 {
width: 714px;
}
input.span11, textarea.span11, .uneditable-input.span11 {
width: 652px;
}
input.span10, textarea.span10, .uneditable-input.span10 {
width: 590px;
}
input.span9, textarea.span9, .uneditable-input.span9 {
width: 528px;
}
input.span8, textarea.span8, .uneditable-input.span8 {
width: 466px;
}
input.span7, textarea.span7, .uneditable-input.span7 {
width: 404px;
}
input.span6, textarea.span6, .uneditable-input.span6 {
width: 342px;
}
input.span5, textarea.span5, .uneditable-input.span5 {
width: 280px;
}
input.span4, textarea.span4, .uneditable-input.span4 {
width: 218px;
}
input.span3, textarea.span3, .uneditable-input.span3 {
width: 156px;
}
input.span2, textarea.span2, .uneditable-input.span2 {
width: 94px;
}
input.span1, textarea.span1, .uneditable-input.span1 {
width: 32px;
}
}
@media (max-width: 980px) {
@media (max-width: 979px) {
body {
padding-top: 0;
}
@ -314,7 +409,12 @@
.navbar .nav > .divider-vertical {
display: none;
}
.navbar .nav > li > a, .navbar .dropdown-menu a {
.navbar .nav .nav-header {
color: #999999;
text-shadow: none;
}
.navbar .nav > li > a,
.navbar .dropdown-menu a {
padding: 6px 15px;
font-weight: bold;
color: #999999;
@ -325,7 +425,8 @@
.navbar .dropdown-menu li + li a {
margin-bottom: 2px;
}
.navbar .nav > li > a:hover, .navbar .dropdown-menu a:hover {
.navbar .nav > li > a:hover,
.navbar .dropdown-menu a:hover {
background-color: #222222;
}
.navbar .dropdown-menu {
@ -346,13 +447,15 @@
-moz-box-shadow: none;
box-shadow: none;
}
.navbar .dropdown-menu:before, .navbar .dropdown-menu:after {
.navbar .dropdown-menu:before,
.navbar .dropdown-menu:after {
display: none;
}
.navbar .dropdown-menu .divider {
display: none;
}
.navbar-form, .navbar-search {
.navbar-form,
.navbar-search {
float: none;
padding: 9px 15px;
margin: 9px 0;
@ -381,6 +484,7 @@
@media (min-width: 980px) {
.nav-collapse.collapse {
height: auto !important;
overflow: visible !important;
}
}
@media (min-width: 1200px) {
@ -388,7 +492,8 @@
margin-left: -30px;
*zoom: 1;
}
.row:before, .row:after {
.row:before,
.row:after {
display: table;
content: "";
}
@ -399,80 +504,89 @@
float: left;
margin-left: 30px;
}
.span1 {
width: 70px;
.container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 1170px;
}
.span2 {
width: 170px;
}
.span3 {
width: 270px;
}
.span4 {
width: 370px;
}
.span5 {
width: 470px;
}
.span6 {
width: 570px;
}
.span7 {
width: 670px;
}
.span8 {
width: 770px;
}
.span9 {
width: 870px;
}
.span10 {
width: 970px;
.span12 {
width: 1170px;
}
.span11 {
width: 1070px;
}
.span12, .container {
width: 1170px;
.span10 {
width: 970px;
}
.offset1 {
margin-left: 130px;
.span9 {
width: 870px;
}
.offset2 {
margin-left: 230px;
.span8 {
width: 770px;
}
.offset3 {
margin-left: 330px;
.span7 {
width: 670px;
}
.offset4 {
margin-left: 430px;
.span6 {
width: 570px;
}
.offset5 {
margin-left: 530px;
.span5 {
width: 470px;
}
.offset6 {
margin-left: 630px;
.span4 {
width: 370px;
}
.offset7 {
margin-left: 730px;
.span3 {
width: 270px;
}
.offset8 {
margin-left: 830px;
.span2 {
width: 170px;
}
.offset9 {
margin-left: 930px;
.span1 {
width: 70px;
}
.offset12 {
margin-left: 1230px;
}
.offset11 {
margin-left: 1130px;
}
.offset10 {
margin-left: 1030px;
}
.offset11 {
margin-left: 1130px;
.offset9 {
margin-left: 930px;
}
.offset8 {
margin-left: 830px;
}
.offset7 {
margin-left: 730px;
}
.offset6 {
margin-left: 630px;
}
.offset5 {
margin-left: 530px;
}
.offset4 {
margin-left: 430px;
}
.offset3 {
margin-left: 330px;
}
.offset2 {
margin-left: 230px;
}
.offset1 {
margin-left: 130px;
}
.row-fluid {
width: 100%;
*zoom: 1;
}
.row-fluid:before, .row-fluid:after {
.row-fluid:before,
.row-fluid:after {
display: table;
content: "";
}
@ -486,77 +600,82 @@
.row-fluid > [class*="span"]:first-child {
margin-left: 0;
}
.row-fluid .span1 {
width: 5.982905983%;
}
.row-fluid .span2 {
width: 14.529914530000001%;
}
.row-fluid .span3 {
width: 23.076923077%;
}
.row-fluid .span4 {
width: 31.623931624%;
}
.row-fluid .span5 {
width: 40.170940171000005%;
}
.row-fluid .span6 {
width: 48.717948718%;
}
.row-fluid .span7 {
width: 57.264957265%;
}
.row-fluid .span8 {
width: 65.81196581200001%;
}
.row-fluid .span9 {
width: 74.358974359%;
}
.row-fluid .span10 {
width: 82.905982906%;
}
.row-fluid .span11 {
width: 91.45299145300001%;
}
.row-fluid .span12 {
.row-fluid > .span12 {
width: 100%;
}
input.span1, textarea.span1, .uneditable-input.span1 {
width: 60px;
.row-fluid > .span11 {
width: 91.45299145300001%;
}
input.span2, textarea.span2, .uneditable-input.span2 {
width: 160px;
.row-fluid > .span10 {
width: 82.905982906%;
}
input.span3, textarea.span3, .uneditable-input.span3 {
width: 260px;
.row-fluid > .span9 {
width: 74.358974359%;
}
input.span4, textarea.span4, .uneditable-input.span4 {
width: 360px;
.row-fluid > .span8 {
width: 65.81196581200001%;
}
input.span5, textarea.span5, .uneditable-input.span5 {
width: 460px;
.row-fluid > .span7 {
width: 57.264957265%;
}
input.span6, textarea.span6, .uneditable-input.span6 {
width: 560px;
.row-fluid > .span6 {
width: 48.717948718%;
}
input.span7, textarea.span7, .uneditable-input.span7 {
width: 660px;
.row-fluid > .span5 {
width: 40.170940171000005%;
}
input.span8, textarea.span8, .uneditable-input.span8 {
width: 760px;
.row-fluid > .span4 {
width: 31.623931624%;
}
input.span9, textarea.span9, .uneditable-input.span9 {
width: 860px;
.row-fluid > .span3 {
width: 23.076923077%;
}
input.span10, textarea.span10, .uneditable-input.span10 {
width: 960px;
.row-fluid > .span2 {
width: 14.529914530000001%;
}
.row-fluid > .span1 {
width: 5.982905983%;
}
input,
textarea,
.uneditable-input {
margin-left: 0;
}
input.span12, textarea.span12, .uneditable-input.span12 {
width: 1160px;
}
input.span11, textarea.span11, .uneditable-input.span11 {
width: 1060px;
}
input.span12, textarea.span12, .uneditable-input.span12 {
width: 1160px;
input.span10, textarea.span10, .uneditable-input.span10 {
width: 960px;
}
input.span9, textarea.span9, .uneditable-input.span9 {
width: 860px;
}
input.span8, textarea.span8, .uneditable-input.span8 {
width: 760px;
}
input.span7, textarea.span7, .uneditable-input.span7 {
width: 660px;
}
input.span6, textarea.span6, .uneditable-input.span6 {
width: 560px;
}
input.span5, textarea.span5, .uneditable-input.span5 {
width: 460px;
}
input.span4, textarea.span4, .uneditable-input.span4 {
width: 360px;
}
input.span3, textarea.span3, .uneditable-input.span3 {
width: 260px;
}
input.span2, textarea.span2, .uneditable-input.span2 {
width: 160px;
}
input.span1, textarea.span1, .uneditable-input.span1 {
width: 60px;
}
.thumbnails {
margin-left: -30px;

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB