data-fields
Version:
Render fields for various types of input.
1,634 lines (1,388 loc) • 435 kB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var vraf = require('virtual-raf')
var h = require('virtual-dom/h')
var createField = require('../geojson')
function inputField (state) {
var field = createField(h, {
editable: true,
zoom: 12,
value: state.geojson,
center: [47.621958, -122.33636]
})
return field
}
function displayField (state) {
var field = createField(h, {
zoom: 12,
editable: false,
center: [47.621958, -122.33636]
})
// field.on('update', function (e, geojson) {
// console.log('update?', e, geojson)
// state.geojson = geojson
// tree.update(state)
// })
return field
}
function render (state) {
return h('div.fields', [
h('div.editable', [inputField(state)]),
h('div.static', [displayField(state)])
])
}
var initialState = {
geojson: { type: 'FeatureCollection', features: [] }
}
var tree = vraf(initialState, render, require('virtual-dom'))
document.body.querySelector('#geojson-basic').appendChild(tree.render())
},{"../geojson":10,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],2:[function(require,module,exports){
var vraf = require('virtual-raf')
var h = require('virtual-dom/h')
var form = require('data-form')
var initialState = {
properties: {
location: {
key: 'location',
name: 'location',
type: ['geoJSON']
}
},
row: {
value: { location: { type: 'Feature', geometry: { type: 'Point', coordinates: [-122.33636, 47.621958] } } }
}
}
function onupdate (e, state) {
tree.update(state)
}
function render (state) {
state.onupdate = onupdate
return form(h, state)
}
var tree = vraf(initialState, render, require('virtual-dom'))
document.body.querySelector('#geojson-form').appendChild(tree.render())
},{"data-form":29,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],3:[function(require,module,exports){
var h = require('virtual-dom/h')
var vraf = require('virtual-raf')
var createMap = require('../utils/map')
function render (state) {
console.log(state.geojson)
return h('div.widget', createMap(state.geojson, {
editable: false,
zoom: 12,
setView: true,
center: [47.621958, -122.33636],
accessToken: 'pk.eyJ1Ijoic2V0aHZpbmNlbnQiLCJhIjoiSXZZXzZnUSJ9.Nr_zKa-4Ztcmc1Ypl0k5nw',
onclick: newPoint
}))
function newPoint (e) {
console.log(e)
state.geojson.features.push({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [e.latlng.lng, e.latlng.lat]
}
})
tree.update(state)
}
}
var initialState = {
geojson: { type: 'FeatureCollection', features: [] }
}
var tree = vraf(initialState, render, require('virtual-dom'))
document.body.querySelector('#geojson-widget').appendChild(tree.render())
},{"../utils/map":94,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],4:[function(require,module,exports){
var vraf = require('virtual-raf')
var h = require('virtual-dom/h')
var createField = require('../image')
function editableField (state) {
var field = createField(h, { value: state.imageURL, oninput: oninput })
function oninput (e) {
tree.update({ imageURL: e.target.value })
}
return field
}
function staticField (state) {
return createField(h, { value: state.imageURL, editable: false })
}
function render (state) {
return h('div.fields', [
h('div.editable', [editableField(state)]),
h('div.static', [staticField(state)])
])
}
var tree = vraf({ imageURL: 'http://placehold.it/50x50' }, render, require('virtual-dom'))
document.body.querySelector('#image').appendChild(tree.render())
},{"../image":11,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],5:[function(require,module,exports){
require('./list')
require('./string')
require('./url')
require('./image')
require('./number')
require('./geojson-basic')
require('./geojson-form')
require('./geojson-widget')
},{"./geojson-basic":1,"./geojson-form":2,"./geojson-widget":3,"./image":4,"./list":6,"./number":7,"./string":8,"./url":9}],6:[function(require,module,exports){
var vraf = require('virtual-raf')
var h = require('virtual-dom/h')
var createField = require('../list')
function inputField (state) {
var field = createField(h, state)
return field
}
function staticField (state) {
var field = createField(h, {
items: state.items,
keys: state.keys,
editable: false
})
return field
}
function render (state) {
return h('div.fields', [
h('div.editable', [inputField(state)]),
h('div.static', [staticField(state)])
])
}
var state = {
items: ['hi', 'ok', 'awesome'],
keys: true
}
state.removeItem = function removeItem (e, items) {
state.items = items
tree.update(state)
}
state.onsubmit = function onsubmit (e, items, item) {
state.items = items
tree.update(state)
}
var tree = vraf(state, render, require('virtual-dom'))
document.body.querySelector('#list').appendChild(tree.render())
},{"../list":12,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],7:[function(require,module,exports){
var vraf = require('virtual-raf')
var h = require('virtual-dom/h')
var numberField = require('../number')
function editableField (state) {
var field = numberField(h, {
value: state.value,
oninput: oninput
})
function oninput (e) {
tree.update({ value: e.target.value })
}
return field
}
function staticField (state) {
var field = numberField(h, {
value: state.value,
editable: false
})
return field
}
function render (state) {
return h('div.fields', [
h('div.editable', [editableField(state)]),
h('div.static', [staticField(state)])
])
}
var tree = vraf({ value: 1000 }, render, require('virtual-dom'))
document.body.querySelector('#number').appendChild(tree.render())
},{"../number":90,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],8:[function(require,module,exports){
var vraf = require('virtual-raf')
var h = require('virtual-dom/h')
var stringField = require('../string')
function editableField (state) {
var field = stringField(h, {
value: state.message,
oninput: oninput
})
function oninput (e) {
tree.update({ message: e.target.value })
}
return field
}
function staticField (state) {
var field = stringField(h, {
value: state.message,
editable: false
})
return field
}
function render (state) {
return h('div.fields', [
h('div.editable', [editableField(state)]),
h('div.static', [staticField(state)])
])
}
var tree = vraf({ message: 'hi' }, render, require('virtual-dom'))
document.body.querySelector('#string').appendChild(tree.render())
},{"../string":91,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],9:[function(require,module,exports){
var vraf = require('virtual-raf')
var h = require('virtual-dom/h')
var createField = require('../url')
function editableField (state) {
var field = createField(h, {
value: state.url,
oninput: oninput
})
function oninput (e) {
tree.update({ url: e.target.value })
}
return field
}
function staticField (state) {
return createField(h, { editable: false }, state.url)
}
function render (state) {
return h('div.fields', [
h('div.editable', [editableField(state)]),
h('div.static', [staticField(state)])
])
}
var tree = vraf({ url: 'example.com' }, render, require('virtual-dom'))
document.body.querySelector('#url').appendChild(tree.render())
},{"../url":92,"virtual-dom":62,"virtual-dom/h":61,"virtual-raf":87}],10:[function(require,module,exports){
var extend = require('xtend')
var createMap = require('./utils/map')
var createClassName = require('./utils/classname')
var defaultProps = {
tagName: 'div',
editable: true,
size: 'normal',
attributes: {}
}
/**
Create a virtual-dom geojson data-field for use with [data-ui](https://github.com/editdata/data-ui).
* @name createGeoJSONField
* @param {Object} options an options object, including any properties you can pass to leaflet & virtual-dom/h
* @param {String} options.accessToken mapbox access token for using their API
* @param {Object} options.tileLayer Leaflet tilelayer, default is osm tiles
* @param {String} options.imagePath path to leaflet images
* @param {Boolean} options.editable false for static mode, default is true for editable mode
* @returns field
* @example
* var createGeoJSONField = require('data-field-geojson')
* var field = createGeoJSONField(h, options, geojsonObject)
*/
module.exports = function createGeoJSONField (h, options, geojsonObject) {
options = extend(defaultProps, options)
options.dataType = 'geojson'
var value = geojsonObject || options.value
var map = createMap(value, options)
options.className = createClassName(options)
return h(options.tagName, options, map)
}
},{"./utils/classname":93,"./utils/map":94,"xtend":89}],11:[function(require,module,exports){
var addhttp = require('addhttp')
var extend = require('xtend')
var createClassName = require('./utils/classname')
var defaultProps = {
tagName: 'input',
editable: true,
size: 'normal',
attributes: {}
}
/**
* Render a virtual-dom image data-field.
* @param {function} h virtual-dom `h` function
* @param {Object} options options object for `h`
* @param {Boolean} options.display false for static mode, default is true for editable mode
* @param {String} options.value any image url
* @returns virtual-dom tree
* @name createImageField
* @example
* var createImageField = require('data-field-image')
* var field = createImageField(h, { value: 'http://example.com/example.jpg' })
*/
module.exports = function createImageField (h, options, value) {
options = extend(defaultProps, options)
options.dataType = 'image'
options.src = addhttp(value || options.src || options.value)
options.className = createClassName(options)
delete options.size
if (!options.editable) options.tagName = 'img'
return h(options.tagName, options, options.src)
}
},{"./utils/classname":93,"addhttp":13,"xtend":89}],12:[function(require,module,exports){
var extend = require('xtend')
var convert = require('object-array-converter')
var createClassName = require('data-field-classname')
var listEditor = require('list-editor')
var isarray = require('isarray')
var defaultProps = {
tagName: 'div',
editable: true,
size: 'normal',
fieldType: 'input',
attributes: {}
}
/**
* Create a virtual-dom list (object or array) data-field for use with [data-ui](https://github.com/editdata/data-ui).
* @param {function} h virtual-dom `h` function
* @param {Object} properties an options object, including any properties you can pass to virtual-dom/h
* @param {Boolean} properties.display true for display mode, default is false for input mode
* @param {Boolean} properties.keys, false for array mode, default is true for object mode
* @param {Object} properties.value an array or flat object
* @param {Array} properties.value an array or flat object
* @param {Object} value an array or flat object
* @param {Array} value an array or flat object
* @returns virtual-dom tree
* @name createListField
* @example
* var createListField = require('data-field-string')
* var field = createListField()
* var tree = field.render(h, properties, ['a', 'b', 'c'])
*/
module.exports = function createListField (h, options, value) {
options = extend(defaultProps, options)
var keys = options.keys
value = value || options.value
options.items = value || options.items
options.dataType = 'list'
if (isarray(value)) value = convert.toObject(value)
var items = []
if (!options.editable) {
options.tagName = 'ul'
items = Object.keys(options.items).map(function (key) {
var item = options.items[key]
var el = []
if (keys) el.push(h('span.data-field-list-key', key + ': '))
el.push(h('span.data-field-list-value', item))
return h('li.data-field-list-item', el)
})
} else {
items = [listEditor(h, options)]
}
options.className = createClassName(options)
return h(options.tagName, options, items)
}
},{"data-field-classname":18,"isarray":45,"list-editor":50,"object-array-converter":52,"xtend":89}],13:[function(require,module,exports){
module.exports = function addhttp (url) {
if (!/^https?\:\/\//.test(url)) {
url = 'http://' + url
}
return url
}
},{}],14:[function(require,module,exports){
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com>
//
// 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 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.
// when used in node, this will actually load the util module we depend on
// versus loading the builtin util module as happens otherwise
// this is a bug in node module loading as far as I am concerned
var util = require('util/');
var pSlice = Array.prototype.slice;
var hasOwn = Object.prototype.hasOwnProperty;
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.
var assert = module.exports = ok;
// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
// actual: actual,
// expected: expected })
assert.AssertionError = function AssertionError(options) {
this.name = 'AssertionError';
this.actual = options.actual;
this.expected = options.expected;
this.operator = options.operator;
if (options.message) {
this.message = options.message;
this.generatedMessage = false;
} else {
this.message = getMessage(this);
this.generatedMessage = true;
}
var stackStartFunction = options.stackStartFunction || fail;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, stackStartFunction);
}
else {
// non v8 browsers so we can have a stacktrace
var err = new Error();
if (err.stack) {
var out = err.stack;
// try to strip useless frames
var fn_name = stackStartFunction.name;
var idx = out.indexOf('\n' + fn_name);
if (idx >= 0) {
// once we have located the function frame
// we need to strip out everything before it (and its line)
var next_line = out.indexOf('\n', idx + 1);
out = out.substring(next_line + 1);
}
this.stack = out;
}
}
};
// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);
function replacer(key, value) {
if (util.isUndefined(value)) {
return '' + value;
}
if (util.isNumber(value) && !isFinite(value)) {
return value.toString();
}
if (util.isFunction(value) || util.isRegExp(value)) {
return value.toString();
}
return value;
}
function truncate(s, n) {
if (util.isString(s)) {
return s.length < n ? s : s.slice(0, n);
} else {
return s;
}
}
function getMessage(self) {
return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
self.operator + ' ' +
truncate(JSON.stringify(self.expected, replacer), 128);
}
// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.
// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided. All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.
function fail(actual, expected, message, operator, stackStartFunction) {
throw new assert.AssertionError({
message: message,
actual: actual,
expected: expected,
operator: operator,
stackStartFunction: stackStartFunction
});
}
// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;
// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.
function ok(value, message) {
if (!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;
// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);
assert.equal = function equal(actual, expected, message) {
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};
// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);
assert.notEqual = function notEqual(actual, expected, message) {
if (actual == expected) {
fail(actual, expected, message, '!=', assert.notEqual);
}
};
// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);
assert.deepEqual = function deepEqual(actual, expected, message) {
if (!_deepEqual(actual, expected)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};
function _deepEqual(actual, expected) {
// 7.1. All identical values are equivalent, as determined by ===.
if (actual === expected) {
return true;
} else if (util.isBuffer(actual) && util.isBuffer(expected)) {
if (actual.length != expected.length) return false;
for (var i = 0; i < actual.length; i++) {
if (actual[i] !== expected[i]) return false;
}
return true;
// 7.2. If the expected value is a Date object, the actual value is
// equivalent if it is also a Date object that refers to the same time.
} else if (util.isDate(actual) && util.isDate(expected)) {
return actual.getTime() === expected.getTime();
// 7.3 If the expected value is a RegExp object, the actual value is
// equivalent if it is also a RegExp object with the same source and
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
} else if (util.isRegExp(actual) && util.isRegExp(expected)) {
return actual.source === expected.source &&
actual.global === expected.global &&
actual.multiline === expected.multiline &&
actual.lastIndex === expected.lastIndex &&
actual.ignoreCase === expected.ignoreCase;
// 7.4. Other pairs that do not both pass typeof value == 'object',
// equivalence is determined by ==.
} else if (!util.isObject(actual) && !util.isObject(expected)) {
return actual == expected;
// 7.5 For all other Object pairs, including Array objects, equivalence is
// determined by having the same number of owned properties (as verified
// with Object.prototype.hasOwnProperty.call), the same set of keys
// (although not necessarily the same order), equivalent values for every
// corresponding key, and an identical 'prototype' property. Note: this
// accounts for both named and indexed properties on Arrays.
} else {
return objEquiv(actual, expected);
}
}
function isArguments(object) {
return Object.prototype.toString.call(object) == '[object Arguments]';
}
function objEquiv(a, b) {
if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
return false;
// an identical 'prototype' property.
if (a.prototype !== b.prototype) return false;
// if one is a primitive, the other must be same
if (util.isPrimitive(a) || util.isPrimitive(b)) {
return a === b;
}
var aIsArgs = isArguments(a),
bIsArgs = isArguments(b);
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
return false;
if (aIsArgs) {
a = pSlice.call(a);
b = pSlice.call(b);
return _deepEqual(a, b);
}
var ka = objectKeys(a),
kb = objectKeys(b),
key, i;
// having the same number of owned properties (keys incorporates
// hasOwnProperty)
if (ka.length != kb.length)
return false;
//the same set of keys (although not necessarily the same order),
ka.sort();
kb.sort();
//~~~cheap key test
for (i = ka.length - 1; i >= 0; i--) {
if (ka[i] != kb[i])
return false;
}
//equivalent values for every corresponding key, and
//~~~possibly expensive deep test
for (i = ka.length - 1; i >= 0; i--) {
key = ka[i];
if (!_deepEqual(a[key], b[key])) return false;
}
return true;
}
// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
if (_deepEqual(actual, expected)) {
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
}
};
// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);
assert.strictEqual = function strictEqual(actual, expected, message) {
if (actual !== expected) {
fail(actual, expected, message, '===', assert.strictEqual);
}
};
// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
if (actual === expected) {
fail(actual, expected, message, '!==', assert.notStrictEqual);
}
};
function expectedException(actual, expected) {
if (!actual || !expected) {
return false;
}
if (Object.prototype.toString.call(expected) == '[object RegExp]') {
return expected.test(actual);
} else if (actual instanceof expected) {
return true;
} else if (expected.call({}, actual) === true) {
return true;
}
return false;
}
function _throws(shouldThrow, block, expected, message) {
var actual;
if (util.isString(expected)) {
message = expected;
expected = null;
}
try {
block();
} catch (e) {
actual = e;
}
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
(message ? ' ' + message : '.');
if (shouldThrow && !actual) {
fail(actual, expected, 'Missing expected exception' + message);
}
if (!shouldThrow && expectedException(actual, expected)) {
fail(actual, expected, 'Got unwanted exception' + message);
}
if ((shouldThrow && actual && expected &&
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
throw actual;
}
}
// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);
assert.throws = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [true].concat(pSlice.call(arguments)));
};
// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments)));
};
assert.ifError = function(err) { if (err) {throw err;}};
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) {
if (hasOwn.call(obj, key)) keys.push(key);
}
return keys;
};
},{"util/":58}],15:[function(require,module,exports){
},{}],16:[function(require,module,exports){
/*!
* Cross-Browser Split 1.1.1
* Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
* Available under the MIT License
* ECMAScript compliant, uniform cross-browser split method
*/
/**
* Splits a string into an array of strings using a regex or string separator. Matches of the
* separator are not included in the result array. However, if `separator` is a regex that contains
* capturing groups, backreferences are spliced into the result each time `separator` is matched.
* Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
* cross-browser.
* @param {String} str String to split.
* @param {RegExp|String} separator Regex or string to use for separating the string.
* @param {Number} [limit] Maximum number of items to include in the result array.
* @returns {Array} Array of substrings.
* @example
*
* // Basic use
* split('a b c d', ' ');
* // -> ['a', 'b', 'c', 'd']
*
* // With limit
* split('a b c d', ' ', 2);
* // -> ['a', 'b']
*
* // Backreferences in result array
* split('..word1 word2..', /([a-z]+)(\d+)/i);
* // -> ['..', 'word', '1', ' ', 'word', '2', '..']
*/
module.exports = (function split(undef) {
var nativeSplit = String.prototype.split,
compliantExecNpcg = /()??/.exec("")[1] === undef,
// NPCG: nonparticipating capturing group
self;
self = function(str, separator, limit) {
// If `separator` is not a regex, use `nativeSplit`
if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
return nativeSplit.call(str, separator, limit);
}
var output = [],
flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6
(separator.sticky ? "y" : ""),
// Firefox 3+
lastLastIndex = 0,
// Make `global` and avoid `lastIndex` issues by working with a copy
separator = new RegExp(separator.source, flags + "g"),
separator2, match, lastIndex, lastLength;
str += ""; // Type-convert
if (!compliantExecNpcg) {
// Doesn't need flags gy, but they don't hurt
separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
}
/* Values for `limit`, per the spec:
* If undefined: 4294967295 // Math.pow(2, 32) - 1
* If 0, Infinity, or NaN: 0
* If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
* If negative number: 4294967296 - Math.floor(Math.abs(limit))
* If other: Type-convert, then use the above rules
*/
limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1
limit >>> 0; // ToUint32(limit)
while (match = separator.exec(str)) {
// `separator.lastIndex` is not reliable cross-browser
lastIndex = match.index + match[0].length;
if (lastIndex > lastLastIndex) {
output.push(str.slice(lastLastIndex, match.index));
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if (!compliantExecNpcg && match.length > 1) {
match[0].replace(separator2, function() {
for (var i = 1; i < arguments.length - 2; i++) {
if (arguments[i] === undef) {
match[i] = undef;
}
}
});
}
if (match.length > 1 && match.index < str.length) {
Array.prototype.push.apply(output, match.slice(1));
}
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= limit) {
break;
}
}
if (separator.lastIndex === match.index) {
separator.lastIndex++; // Avoid an infinite loop
}
}
if (lastLastIndex === str.length) {
if (lastLength || !separator.test("")) {
output.push("");
}
} else {
output.push(str.slice(lastLastIndex));
}
return output.length > limit ? output.slice(0, limit) : output;
};
return self;
})();
},{}],17:[function(require,module,exports){
/**
* cuid.js
* Collision-resistant UID generator for browsers and node.
* Sequential for fast db lookups and recency sorting.
* Safe for element IDs and server-side lookups.
*
* Extracted from CLCTR
*
* Copyright (c) Eric Elliott 2012
* MIT License
*/
/*global window, navigator, document, require, process, module */
(function (app) {
'use strict';
var namespace = 'cuid',
c = 0,
blockSize = 4,
base = 36,
discreteValues = Math.pow(base, blockSize),
pad = function pad(num, size) {
var s = "000000000" + num;
return s.substr(s.length-size);
},
randomBlock = function randomBlock() {
return pad((Math.random() *
discreteValues << 0)
.toString(base), blockSize);
},
safeCounter = function () {
c = (c < discreteValues) ? c : 0;
c++; // this is not subliminal
return c - 1;
},
api = function cuid() {
// Starting with a lowercase letter makes
// it HTML element ID friendly.
var letter = 'c', // hard-coded allows for sequential access
// timestamp
// warning: this exposes the exact date and time
// that the uid was created.
timestamp = (new Date().getTime()).toString(base),
// Prevent same-machine collisions.
counter,
// A few chars to generate distinct ids for different
// clients (so different computers are far less
// likely to generate the same id)
fingerprint = api.fingerprint(),
// Grab some more chars from Math.random()
random = randomBlock() + randomBlock();
counter = pad(safeCounter().toString(base), blockSize);
return (letter + timestamp + counter + fingerprint + random);
};
api.slug = function slug() {
var date = new Date().getTime().toString(36),
counter,
print = api.fingerprint().slice(0,1) +
api.fingerprint().slice(-1),
random = randomBlock().slice(-2);
counter = safeCounter().toString(36).slice(-4);
return date.slice(-2) +
counter + print + random;
};
api.globalCount = function globalCount() {
// We want to cache the results of this
var cache = (function calc() {
var i,
count = 0;
for (i in window) {
count++;
}
return count;
}());
api.globalCount = function () { return cache; };
return cache;
};
api.fingerprint = function browserPrint() {
return pad((navigator.mimeTypes.length +
navigator.userAgent.length).toString(36) +
api.globalCount().toString(36), 4);
};
// don't change anything from here down.
if (app.register) {
app.register(namespace, api);
} else if (typeof module !== 'undefined') {
module.exports = api;
} else {
app[namespace] = api;
}
}(this.applitude || this));
},{}],18:[function(require,module,exports){
var assert = require('assert')
module.exports = function createClassName (options) {
options = options || {}
assert.ok(options.dataType, 'options.dataType property required')
assert.ok(options.fieldType, 'options.fieldType property required')
assert.ok(options.size, 'options.size property required')
return 'data-field data-field-' + options.dataType + ' data-field-' + options.fieldType + ' data-field-' + options.fieldType + '-' + options.size
}
},{"assert":14}],19:[function(require,module,exports){
var extend = require('xtend')
var createMap = require('./utils/map')
var createClassName = require('./utils/classname')
var defaultProps = {
tagName: 'div',
editable: true,
size: 'normal',
attributes: {}
}
/**
Create a virtual-dom geojson data-field for use with [data-ui](https://github.com/editdata/data-ui).
* @name createGeoJSONField
* @param {Object} options an options object, including any properties you can pass to leaflet & virtual-dom/h
* @param {String} options.accessToken mapbox access token for using their API
* @param {Object} options.tileLayer Leaflet tilelayer, default is osm tiles
* @param {String} options.imagePath path to leaflet images
* @param {Boolean} options.editable false for static mode, default is true for editable mode
* @returns field
* @example
* var createGeoJSONField = require('data-field-geojson')
* var field = createGeoJSONField(h, options, geojsonObject)
*/
module.exports = function createGeoJSONField (h, options, geojsonObject) {
options = extend(defaultProps, options)
options.dataType = 'geojson'
var value = geojsonObject || options.value
var map = createMap(value, options)
options.className = createClassName(options)
return h(options.tagName, options, map)
}
},{"./utils/classname":26,"./utils/map":27,"xtend":89}],20:[function(require,module,exports){
arguments[4][11][0].apply(exports,arguments)
},{"./utils/classname":26,"addhttp":13,"dup":11,"xtend":89}],21:[function(require,module,exports){
module.exports = {
string: require('./string'),
number: require('./number'),
url: require('./url'),
geoJSON: require('./geoJSON'),
image: require('./image'),
list: require('./list')
}
},{"./geoJSON":19,"./image":20,"./list":22,"./number":23,"./string":24,"./url":25}],22:[function(require,module,exports){
var extend = require('xtend')
var convert = require('object-array-converter')
var createClassName = require('data-field-classname')
var listEditor = require('list-editor')
var isarray = require('isarray')
var defaultProps = {
tagName: 'div',
editable: true,
size: 'normal',
fieldType: 'input',
attributes: {}
}
/**
* Create a virtual-dom list (object or array) data-field for use with [data-ui](https://github.com/editdata/data-ui).
* @param {function} h virtual-dom `h` function
* @param {Object} properties an options object, including any properties you can pass to virtual-dom/h
* @param {Boolean} properties.display true for display mode, default is false for input mode
* @param {Boolean} properties.keys, false for array mode, default is true for object mode
* @param {Object} properties.value an array or flat object
* @param {Array} properties.value an array or flat object
* @param {Object} value an array or flat object
* @param {Array} value an array or flat object
* @returns virtual-dom tree
* @name createListField
* @example
* var createListField = require('data-field-string')
* var field = createListField()
* var tree = field.render(h, properties, ['a', 'b', 'c'])
*/
module.exports = function createListField (h, options, value) {
options = extend(defaultProps, options)
var keys = options.keys
value = value || options.value
options.items = value
options.dataType = 'list'
if (isarray(value)) value = convert.toObject(value)
var items = []
if (!options.editable) {
options.tagName = 'ul'
items = Object.keys(value).map(function (key) {
var item = value[key]
var el = []
if (keys) el.push(h('span.data-field-list-key', key + ': '))
el.push(h('span.data-field-list-value', item))
return h('li.data-field-list-item', el)
})
} else {
items = [listEditor({ items: value, keys: keys }, options)]
}
options.className = createClassName(options)
return h(options.tagName, options, items)
}
},{"data-field-classname":18,"isarray":45,"list-editor":50,"object-array-converter":52,"xtend":89}],23:[function(require,module,exports){
var extend = require('xtend')
var createClassName = require('./utils/classname')
var defaultProps = {
tagName: 'input',
attributes: {},
editable: true,
size: 'normal'
}
/**
* Create a virtual-dom number data-field for use with [data-ui](https://github.com/editdata/data-ui).
* @param {function} h virtual-dom `h` function
* @param {Object} options Options object, including any properties you can pass to virtual-dom/h
* @param {Boolean} options.editable false for static mode, default is true for editable mode
* @param {String} options.value any number
* @returns virtual-dom tree
* @name createStringField
* @example
* var createStringField = require('data-field-string')
* var field = createStringField(h, { value: 1000 })
*/
module.exports = function NumberField (h, options, value) {
options = extend(defaultProps, options)
options.value = value || options.value
options.type = options.dataType = 'number'
options.fieldType = 'input'
options.className = createClassName(options)
delete options.size
if (!options.editable) options.tagName = 'div'
return h(options.tagName, options, options.value)
}
},{"./utils/classname":26,"xtend":89}],24:[function(require,module,exports){
var extend = require('xtend')
var createClassName = require('./utils/classname')
var defaultProps = {
tagName: 'textarea',
editable: true,
size: 'normal',
attributes: {}
}
/**
* Create a virtual-dom string data-field for use with [data-ui](https://github.com/editdata/data-ui).
* @param {Function} h virtual-dom `h` function
* @param {Object} options Options object, including any properties you can pass to virtual-dom/h
* @param {Boolean} options.editable false for a static field, default is true for an editable field
* @param {String} options.value any string
* @returns virtual-dom tree
* @name createStringField
* @example
* var createStringField = require('data-field-string')
* var field = createStringField(h, { value: 'example string' })
*/
module.exports = function createStringField (h, options, value) {
options = extend(defaultProps, options)
options.value = value || options.value
options.dataType = 'string'
if (!options.editable) options.tagName = 'div'
if (options.size === 'small') options.attributes.rows = 1
options.className = createClassName(options)
return h(options.tagName, options, String(options.value))
}
},{"./utils/classname":26,"xtend":89}],25:[function(require,module,exports){
var createClassName = require('./utils/classname')
var extend = require('xtend')
var addhttp = require('addhttp')
var defaultProps = {
tagName: 'input',
editable: true,
size: 'normal',
attributes: {}
}
/**
* Create a virtual-dom url data-field for use with [data-ui](https://github.com/editdata/data-ui).
* @param {Object} options an options object, including any properties you can pass to virtual-dom/h
* @param {Boolean} options.display true for display mode, default is false for input mode
* @returns field
* @name createURLField
* @example
* var createURLField = require('data-field-url')
* var field = createURLField()
* var vtree = field.render(h, {}, 'http://example.com')
*/
module.exports = function URLField (h, options, value) {
options = extend(defaultProps, options)
options.value = value || options.value
options.dataType = 'url'
options.href = addhttp(options.href || options.value)
options.value = options.href
options.className = createClassName(options)
delete options.size
if (!options.editable) options.tagName = 'a'
return h(options.tagName, options, options.href)
}
},{"./utils/classname":26,"addhttp":13,"xtend":89}],26:[function(require,module,exports){
module.exports = function createClassName (options) {
if (!options.hasOwnProperty('dataType')) throw Error('options.dataType property required')
if (!options.hasOwnProperty('editable')) throw Error('options.editable property required')
if (!options.hasOwnProperty('size')) throw Error('options.size property required')
var className = 'data-field'
className += ' data-field-' + options.dataType
if (options.editable) {
className += ' data-field-editable data-field-editable-' + options.size
}
if (options.className) className += ' ' + options.className
return className
}
},{}],27:[function(require,module,exports){
var L = require('leaflet')
require('leaflet-draw')
module.exports = MapWidget
L.Icon.Default.imagePath = 'assets/'
function MapWidget (state, options) {
if (!(this instanceof MapWidget)) return new MapWidget(state, options)
var defaultState = { type: 'FeatureCollection', features: [] }
if (!state || typeof state !== 'object') {
this.data = defaultState
} else if (state.type === 'Feature') {
defaultState.features.push(state)
this.data = defaultState
} else if (state.type === 'FeatureCollection') {
this.data = state
}
this.type = 'Widget'
this.map = null
this.features = null
this.accessToken = options.accessToken
this.display = options.display || false
this.tiles = options.tileLayer || L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' })
this.onclick = options.onclick
this.onedit = options.onedit
this.ondraw = options.ondraw
this.onupdate = options.onupdate
delete options.tiles
delete options.display
delete options.onclick
this.options = options
}
MapWidget.prototype.refresh = function () {
this.map.invalidateSize()
}
MapWidget.prototype.init = function () {
var self = this
var el = document.createElement('div')
el.className = 'data-field-geojson-map-container'
this.map = L.map(el, this.options)
this.tiles.addTo(this.map)
this.features = L.geoJson(this.data)
this.map.addLayer(this.features)
if (this.display) {
this.features.on('click', function (e) {
if (self.onclick) self.onclick(e)
})
} else {
var drawControl = new L.Control.Draw({
edit: { featureGroup: this.features }
})
this.map.addControl(drawControl)
this.map.on('draw:created', function (e) {
self.features.addData(e.layer.toGeoJSON())
if (self.options.ondraw) self.options.ondraw(e, self.features.toGeoJSON())
if (self.options.onupdate) self.options.onupdate(e, self.features.toGeoJSON())
})
this.map.on('draw:edited', function (e) {
if (self.options.onedit) self.options.onedit(e, self.features.toGeoJSON())
if (self.options.onupdate) self.options.onupdate(e, self.features.toGeoJSON())
})
}
window.addEventListener('load', function (e) {
self.map.invalidateSize()
})
return el
}
MapWidget.prototype.update = function (previous, el) {
this.map = this.map || previous.map
this.features = this.features || previous.features
this.features.clearLayers()
this.features.addData(this.data)
}
MapWidget.prototype.destroy = function (el) {}
},{"leaflet":48,"leaflet-draw":47}],28:[function(require,module,exports){
module.exports = function createFormHeader (h, options) {
return h('div.data-form-header', [
h('div.data-form-actions', [
h('button.data-form-action.data-form-action-close.button', {
onclick: options.onclick
}, options.closeButton || 'close')
])
])
}
},{}],29:[function(require,module,exports){
/*global requestAnimationFrame*/
var formatter = require('data-format')()
var fieldTypes = require('data-fields')
var vhook = require('virtual-hook')
var createHeader = require('./header')
module.exports = Form
function Form (h, options) {
var activeColumnKey = options.activeColumnKey
var oninput = options.oninput
var onclick = options.onclick
var ondestroy = options.ondestroy
var onclose = options.onclose
var onupdate = options.onupdate
var properties = options.properties
var row = options.row
var columns = row.value
var fields = []
var header
if (typeof options.header === 'object') {
header = options.header
} else if (options.header !== false) {
header = createHeader(h, { onclick: onClose })
}
function onInput (rowKey, propertyKey) {
return function (event) {
var inputValue = event.target.value
if (oninput) return oninput(event, rowKey, propertyKey, inputValue)
}
}
function onClick (rowKey, propertyKey) {
return function (event) {
if (onclick) return onclick(event, rowKey, propertyKey)
}
}
function onDestroy (event) {
if (ondestroy) return ondestroy(event, row.key)
}
function onClose (event) {
if (onclose) return onclose(event)
}
function onUpdate (event) {
if (onupdate) return onupdate(event)
}
Object.keys(columns).forEach(function (propertyKey) {
var property = formatter.findProperty(properties, propertyKey)
var value = columns[propertyKey]
var rowKey = row.key
var type = property.type[0]
var hooks = {
hook: function (node, prop, prev) {
if (propertyKey === activeColumnKey) {
requestAnimationFrame(function () {
node.focus()
})
}
}
}
var fieldOptions = {
h: h,
custom: vhook(hooks),
id: 'item-property-' + row.key + '-' + propertyKey,
attributes: { 'data-key': propertyKey },
value: columns[propertyKey],
className: 'item-property-value',
oninput: onInput(rowKey, propertyKey),
onclick: onClick(rowKey, propertyKey),
onupdate: onUpdate,
center: [47.621958, -122.33636],
zoom: 12
}
if (type === 'array') { type = 'list' }
if (type === 'object') {
if (value.type && value.type === 'Feature') {
type = 'geoJSON'
} else {
type = 'list'
}
}
var field = fieldTypes[type](h, fieldOptions)
var fieldwrapper = h('div.item-property-wrapper', [
h('span.item-property-label', property.name),
field
])
fields.push(fieldwrapper)
})
return h('div#item.active', [
h('div.item', [
header,
h('button#destroyRow.small.button-orange', {
onclick: onDestroy
}, 'destroy row'),
h('div.item-properties-wrapper', {
attributes: {
'data-key': row.key
}
}, fields)
])
])
}
},{"./header":28,"data-fields":21,"data-format":30,"virtual-hook":86}],30:[function(require,module,exports){
var validator = require('is-my-json-valid')
var extend = require('extend')
var type = require('type-of')
var isgeojson = require('is-geojson')
var cuid = require('cuid')
module.exports = function dataType (options) {
options = options || {}
var keyFormat = options.keyFormat || 'property-'
function findProperty (props, id) {
var name = id.name ? id.name : id
var propkey = id.key ? id.key : id
for (var key in props) {
var nameMatch = props[key].name === name
var keyMatch = props[key].key === propkey
if (nameMatch || keyMatch) return props[key]
}
}
function createProperty (key, value) {
return {
key: keyFormat + cuid(),
name: key,
type: initType(value),
default: null
}
}
function updateProperty (props, id, options) {
var prop = findProperty(props, id)
prop = extend(prop, options)
props[prop.key] = prop
return prop
}
function removeProperty (props, id) {
var prop = findProperty(id)
delete props[prop.key]
}
function validateProperty (props, prop, value) {
if (typeof prop === 'string') {
prop = findProperty(props, prop)
if (!prop) return new Error('Property not found')
}
if (!prop) return new Error('Property, property key, or property name required as second argument')
var validate = validator(props[prop.key])
return validate(value)
}
function convertToKeys (props, row) {
var data = {}
var prop
Object.keys(row).forEach(function (key) {
prop = findProperty(props, key)
if (!prop) {
prop = createProperty(key, row[key])
}
if (!props[prop.key]) {
props[prop.key] = prop
}
data[prop.key] = row[key]
})
return data
}
function convertToNames (props, row) {
var data = {}
var prop
Object.keys(row).forEach(function (key) {
prop = findProperty(props, key)
if (!prop) {
prop = createProperty(key, row[key])
}
data[prop.name] = row[key]
})
return data
}
function convert (props, row, options) {
options = options || {}
if (options.to === 'names') {
return convertToNames(props, row)
} else {
return convertToKeys(props, row)
}
}
function initType (value) {
return [type(value), 'null']
}
function getType (props, key) {
return props[key].type[0]
}
function isType (prop, checkType) {
prop.type.some(function (type) {
return type === checkType
})
}
function toGeoJSON (data, properties, options) {
if (data.data && data.properties) {
options = properties
properties = data.properties
data = data.data
}
options = options || {}
var features = []
data.forEach(function (item, i) {
features[i] = {}
features[i].type = 'Feature'
features[i].id = item.key
features[i].geometry = item.geometry
if (!options.convertToNames) {
features[i].properties = item.value
} else {
features[i].properties = convertToNames(properties, item.value)
}
})
return features
}
function format (data, options) {
options = options || {}
options.key = options.key || 'key'
options.value = options.value || 'value'
var results = {
properties: {},
data: []
}
if (type(data) === 'array') {
data.forEach(function (item) {
var formatted = {
key: null,
value: {},
geometry: { type: 'Point', 'coordinates': [] }
}
if (isgeojson(item) && item.id && item.properties && item.geometry) {
formatted.key = item.id
formatted.value = item.properties
formatted.geometry = item.geometry
} else if (type(item) === 'obj