diff --git a/config.coffee b/config.coffee index c7b8f5e..2c6f6ef 100644 --- a/config.coffee +++ b/config.coffee @@ -10,8 +10,8 @@ exports.config = javascripts: defaultExtension: 'coffee' joinTo: - 'treema.js': /^src/ 'dev/js/treema.js': /^src/ + 'treema.js': /^src/ 'dev/js/treema.spec.js': /^test/ 'treema-utils.js': /^src\/utils/ order: diff --git a/dev/css/treema.css b/dev/css/treema.css index 83df9df..b8ede51 100644 --- a/dev/css/treema.css +++ b/dev/css/treema.css @@ -1,4 +1,8 @@ +.treema-target-of-copy-paste { + transform: translateX(10px); } + .treema-node { + transition: 0.1s ease-in-out transform; user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/dev/index.html b/dev/index.html index 8aeb576..15d3668 100644 --- a/dev/index.html +++ b/dev/index.html @@ -5,7 +5,7 @@ - + diff --git a/dev/js/base.js b/dev/js/base.js index 8f06833..0888352 100644 --- a/dev/js/base.js +++ b/dev/js/base.js @@ -44,6 +44,7 @@ function buildTreemaExample (el, schema, data) { } $(this).tab('show'); }); + el.on('treema-error', function(e) { alert(e.message); }); // so that each demo has unique ids demosMade += 1; @@ -71,4 +72,4 @@ var makeFauxSearchTreemaNodeClass = function (url) { this['super']('searchCallback').apply(this, [newResults]); }; return FauxSearchTreemaNode; -}; \ No newline at end of file +}; diff --git a/dev/js/treema.js b/dev/js/treema.js index 3d0cfc1..da9ced9 100644 --- a/dev/js/treema.js +++ b/dev/js/treema.js @@ -1,3 +1,55 @@ +(function() { + var WebSocket = window.WebSocket || window.MozWebSocket; + var br = window.brunch = (window.brunch || {}); + var ar = br['auto-reload'] = (br['auto-reload'] || {}); + if (!WebSocket || ar.disabled) return; + + var cacheBuster = function(url){ + var date = Math.round(Date.now() / 1000).toString(); + url = url.replace(/(\&|\\?)cacheBuster=\d*/, ''); + return url + (url.indexOf('?') >= 0 ? '&' : '?') +'cacheBuster=' + date; + }; + + var browser = navigator.userAgent.toLowerCase(); + var forceRepaint = ar.forceRepaint || browser.indexOf('chrome') > -1; + + var reloaders = { + page: function(){ + window.location.reload(true); + }, + + stylesheet: function(){ + [].slice + .call(document.querySelectorAll('link[rel="stylesheet"][href]:not([data-autoreload="false"]')) + .forEach(function(link) { + link.href = cacheBuster(link.href); + }); + + // Hack to force page repaint after 25ms. + if (forceRepaint) setTimeout(function() { document.body.offsetHeight; }, 25); + } + }; + var port = ar.port || 9486; + var host = br.server || window.location.hostname || 'localhost'; + + var connect = function(){ + var connection = new WebSocket('ws://' + host + ':' + port); + connection.onmessage = function(event){ + if (ar.disabled) return; + var message = event.data; + var reloader = reloaders[message] || reloaders.page; + reloader(); + }; + connection.onerror = function(){ + if (connection.readyState) connection.close(); + }; + connection.onclose = function(){ + window.setTimeout(connect, 1000); + }; + }; + connect(); +})(); + var TreemaNode, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, @@ -486,12 +538,19 @@ TreemaNode = (function() { } }); return this.$el.keyup(function(e) { + var _ref, _ref1; + if ((_ref = e.which) === 17 || _ref === 91) { + if ((_ref1 = _this.targetOfCopyPaste) != null) { + _ref1.removeClass('treema-target-of-copy-paste'); + } + _this.targetOfCopyPaste = null; + } return delete _this.keysPreviouslyDown[e.which]; }); }; TreemaNode.prototype.manageCopyAndPaste = function(e) { - var el, target, _ref, _ref1, _ref2, + var el, target, _ref, _this = this; el = document.activeElement; if ((el != null) && (el.tagName.toLowerCase() === 'input' && el.type === 'text') || (el.tagName.toLowerCase() === 'textarea' && !$(el).hasClass('treema-clipboard'))) { @@ -511,12 +570,21 @@ TreemaNode = (function() { newData = JSON.parse(newData); } catch (_error) { e = _error; + _this.$el.trigger({ + type: 'treema-error', + message: 'Could not parse pasted data as JSON.' + }); return; } result = target.tv4.validateMultiple(newData, target.schema); if (result.valid) { - return target.set('/', newData); + target.set('/', newData); + return _this.$el.trigger('treema-paste'); } else { + _this.$el.trigger({ + type: 'treema-error', + message: 'Data provided is invalid according to schema.' + }); return console.log("not pasting", newData, "because it's not valid:", result); } }), 5); @@ -530,13 +598,24 @@ TreemaNode = (function() { this.saveScrolls(); this.$clipboardContainer.find('.treema-clipboard').focus().select(); return this.loadScrolls(); - } else if (!(((_ref1 = window.getSelection()) != null ? _ref1.toString() : void 0) || ((_ref2 = document.selection) != null ? _ref2.createRange().text : void 0))) { + } else { this.saveScrolls(); - if (this.$clipboardContainer == null) { + if (!this.$clipboardContainer) { this.$clipboardContainer = $('
').appendTo(this.$el); + this.$clipboardContainer.on('paste', function() { + var _ref1; + return (_ref1 = _this.targetOfCopyPaste) != null ? _ref1.removeClass('treema-target-of-copy-paste') : void 0; + }); + this.$clipboardContainer.on('copy', function() { + var _ref1; + _this.$el.trigger('treema-copy'); + return (_ref1 = _this.targetOfCopyPaste) != null ? _ref1.removeClass('treema-target-of-copy-paste') : void 0; + }); } + this.targetOfCopyPaste = target.$el; + this.targetOfCopyPaste.addClass('treema-target-of-copy-paste'); this.$clipboardContainer.empty().show(); - this.$clipboard = $('').val(JSON.stringify(target.data)).appendTo(this.$clipboardContainer).focus().select(); + this.$clipboard = $('').val(JSON.stringify(target.getData(), null, ' ')).appendTo(this.$clipboardContainer).focus().select(); return this.loadScrolls(); } }; @@ -861,10 +940,7 @@ TreemaNode = (function() { return; } selected = $(ctx.origin).data('instance'); - if (!selected) { - return; - } - if (offset > 0 && aggressive && selected.collection && selected.isClosed()) { + if (offset > 0 && aggressive && selected && selected.collection && selected.isClosed()) { return selected.open(); } targetEl = offset > 0 ? ctx.next : ctx.prev; @@ -1228,7 +1304,9 @@ TreemaNode = (function() { if (this.ordered && childrenContainer.sortable && !this.settings.noSortable) { if (typeof childrenContainer.sortable === "function") { childrenContainer.sortable({ - deactivate: this.orderDataFromUI + deactivate: this.orderDataFromUI, + forcePlaceholderSize: true, + placeholder: 'placeholder' }); } } @@ -1258,12 +1336,18 @@ TreemaNode = (function() { if (!(treema != null ? treema.data : void 0)) { continue; } - treema.keyForParent = index; - this.childrenTreemas[index] = treema; - this.data[index] = treema.data; + if ($.isArray(this.data)) { + treema.keyForParent = index; + this.childrenTreemas[index] = treema; + this.data[index] = treema.data; + } else { + this.childrenTreemas[treema.keyForParent] = treema; + this.data[treema.keyForParent] = treema.data; + } index += 1; } - return this.flushChanges(); + this.flushChanges(); + return this.broadcastChanges(); }; TreemaNode.prototype.close = function(saveChildData) { @@ -3059,23 +3143,18 @@ TreemaNode = (function() { }; ObjectNode.prototype.canAddProperty = function(key) { - var pattern; + var pattern, _ref7; if (this.workingSchema.additionalProperties !== false) { return true; } - if (this.workingSchema.properties[key] != null) { + if (((_ref7 = this.workingSchema.properties) != null ? _ref7[key] : void 0) != null) { return true; } if (this.workingSchema.patternProperties != null) { - if ((function() { - var _results; - _results = []; - for (pattern in this.workingSchema.patternProperties) { - _results.push(RegExp(pattern).test(key)); + for (pattern in this.workingSchema.patternProperties) { + if (RegExp(pattern).test(key)) { + return true; } - return _results; - }).call(this)) { - return true; } } return false; @@ -3436,8 +3515,9 @@ TreemaNode = (function() { maxLines: Infinity }); if (this.schema.aceTheme != null) { - return this.editor.setTheme(this.schema.aceTheme); + this.editor.setTheme(this.schema.aceTheme); } + return this.editor.$blockScrolling = Infinity; }; AceNode.prototype.toggleEdit = function() { @@ -3596,7 +3676,8 @@ TreemaUtils = (function() { return rootData; }; utils.walk = function(data, schema, tv4, callback, path) { - var childPath, childSchema, key, value, workingSchema, workingSchemas, _ref, _results; + var dataType, f, key, value, workingSchema, workingSchemas, _i, _len, _results, _results1, + _this = this; if (path == null) { path = ''; } @@ -3610,19 +3691,34 @@ TreemaUtils = (function() { workingSchemas = this.buildWorkingSchemas(schema, tv4); workingSchema = this.chooseWorkingSchema(data, workingSchemas, tv4); callback(path, data, workingSchema); - if ((_ref = this.type(data)) === 'array' || _ref === 'object') { - _results = []; - for (key in data) { + dataType = this.type(data); + if (dataType === 'array' || dataType === 'object') { + f = function(key, value) { + var childPath, childSchema; value = data[key]; childPath = path.slice(); if (childPath) { childPath += '.'; } childPath += key; - childSchema = this.getChildSchema(key, workingSchema); - _results.push(this.walk(value, childSchema, tv4, callback, childPath)); + childSchema = _this.getChildSchema(key, workingSchema); + return _this.walk(value, childSchema, tv4, callback, childPath); + }; + if (dataType === 'array') { + _results = []; + for (key = _i = 0, _len = data.length; _i < _len; key = ++_i) { + value = data[key]; + _results.push(f(key, value)); + } + return _results; + } else { + _results1 = []; + for (key in data) { + value = data[key]; + _results1.push(f(key, value)); + } + return _results1; } - return _results; } }; utils.getChildSchema = function(key, schema) { diff --git a/dev/js/treema.spec.js b/dev/js/treema.spec.js index 17f7491..99c813f 100644 --- a/dev/js/treema.spec.js +++ b/dev/js/treema.spec.js @@ -84,7 +84,6 @@ keyDown = function($el, which) { schema: schema, callbacks: { change: function() { - console.log('change callback', arguments); return fired.f += 1; } } @@ -170,6 +169,26 @@ keyDown = function($el, which) { return expect(fired.f).toBe(1); }); }); +;describe('canAddProperty', function() { + return it('works when properties is not defined, additionalProperties is false, and patternProperties is defined', function() { + var data, schema, treema; + schema = { + "type": "object", + "patternProperties": { + "^[a-z]+$": {} + }, + "additionalProperties": false + }; + data = {}; + treema = TreemaNode.make(null, { + data: data, + schema: schema + }); + treema.build(); + expect(treema.canAddProperty('test')).toBe(true); + return expect(treema.canAddProperty('1234')).toBe(false); + }); +}); ;describe('defaults', function() { it('shows properties for object nodes which are specified in a default object that are not included in the data', function() { var data, schema, treema; @@ -1148,7 +1167,7 @@ describe('Schemaless', function() { expect(treema.childrenTreemas.name).toBeUndefined(); return expect(treema.childrenTreemas.address).toBeUndefined(); }); - it('removes single elements of a collection one at a time, then the collection itself', function() { + xit('removes single elements of a collection one at a time, then the collection itself', function() { phoneTreema.open(); phoneTreema.childrenTreemas[1].open(); phoneTreema.childrenTreemas[0].select(); @@ -1409,12 +1428,20 @@ describe('Schemaless', function() { expect(phoneTreema.childrenTreemas[1].isDisplaying()).toBeTruthy(); return expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy(); }); - return it('edits the first child in a collection if a collection is selected', function() { + it('edits the first child in a collection if a collection is selected', function() { phoneTreema.open(); phoneTreema.select(); tabKeyPress(phoneTreema.$el); return expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy(); }); + return xit('goes around in a loop', function() { + $('body').append(treema.$el); + addressTreema.select(); + tabKeyPress(treema.$el); + tabKeyPress($(document.activeElement)); + expect(nameTreema.isEditing()).toBeTruthy(); + return treema.$el.remove(); + }); }); ;describe('Mouse click behavior', function() { var metaClick, nameTreema, phoneTreema, schema, shiftClick, treema; @@ -1610,36 +1637,36 @@ describe('Schemaless', function() { "type": "object", "additionalProperties": false, "properties": { - "0": { + "integer": { type: "integer" }, - "1": { + "string": { type: "string" }, - "2": { + "number": { type: "number" }, - "3": { + "null": { type: "null" }, - "4": { + "boolean": { type: "boolean" }, - "5": { + "array": { type: "array", items: { type: 'number', "default": 42 } }, - "6": { + "object": { type: "object" }, - "7": { + "def": { 'default': 1337 } }, - "required": ['0', '1', '2', '3', '4', '5', '6', '7'] + "required": ['integer', 'string', 'number', 'null', 'boolean', 'array', 'object', 'def'] }; data = {}; treema = TreemaNode.make(null, { @@ -1649,17 +1676,17 @@ describe('Schemaless', function() { return treema.build(); }); it('populates all required values with generic data', function() { - expect(treema.get('/0')).toBe(0); - expect(treema.get('/1')).toBe(''); - expect(treema.get('/2')).toBe(0); - expect(treema.get('/3')).toBe(null); - expect(treema.get('/4')).toBe(false); - expect(JSON.stringify(treema.get('/5'))).toBe(JSON.stringify([])); - return expect(JSON.stringify(treema.get('/6'))).toBe(JSON.stringify({})); + expect(treema.get('/integer')).toBe(0); + expect(treema.get('/string')).toBe(''); + expect(treema.get('/number')).toBe(0); + expect(treema.get('/null')).toBe(null); + expect(treema.get('/boolean')).toBe(false); + expect(JSON.stringify(treema.get('/array'))).toBe(JSON.stringify([])); + return expect(JSON.stringify(treema.get('/object'))).toBe(JSON.stringify({})); }); return it('populates required values with defaults', function() { - expect(treema.get('/7')).toBe(1337); - treema.childrenTreemas['5'].addNewChild(); + expect(treema.get('/def')).toBe(1337); + treema.childrenTreemas['array'].addNewChild(); return expect(treema.$el.find('input').val()).toBe('42'); }); }); @@ -1987,7 +2014,7 @@ describe('utilities', function() { }); }); describe('walk', function() { - return it('calls a callback on every piece of data in a JSON object, providing path, data and working schema', function() { + it('calls a callback on every piece of data in a JSON object, providing path, data and working schema', function() { var data, paths, schema, values, _ref, _ref1; schema = { type: 'object', @@ -2018,6 +2045,25 @@ describe('utilities', function() { expect((_ref = data.key1, __indexOf.call(values, _ref) >= 0)).toBe(true); return expect((_ref1 = data.key2, __indexOf.call(values, _ref1) >= 0)).toBe(true); }); + return it('traverses arrays', function() { + var data, foundIt, schema; + schema = { + type: 'array', + items: { + type: 'object', + marker: true + } + }; + data = [{}]; + foundIt = false; + TreemaNode.utils.walk(data, schema, null, function(path, data, schema) { + if (path === '0') { + expect(schema.marker).toBe(true); + return foundIt = true; + } + }); + return expect(foundIt).toBe(true); + }); }); describe('getChildSchema', function() { it('returns child schemas from properties', function() { diff --git a/dev/js/treema.spec.js.map b/dev/js/treema.spec.js.map index 831213d..807386f 100644 --- a/dev/js/treema.spec.js.map +++ b/dev/js/treema.spec.js.map @@ -1 +1 @@ -{"version":3,"file":"dev/js/treema.spec.js","sources":["test/common.coffee","test/ambiguous/type.coffee","test/callbacks/change.coffee","test/default.spec.coffee","test/filter.coffee","test/getters-setters/delete.coffee","test/getters-setters/get.coffee","test/getters-setters/insert.coffee","test/getters-setters/set.coffee","test/initialization.coffee","test/keyboard/arrow-keys.coffee","test/keyboard/delete-key.coffee","test/keyboard/enter-key.coffee","test/keyboard/n-key.coffee","test/keyboard/tab-key.coffee","test/mouse-click.coffee","test/readOnly.coffee","test/required.spec.coffee","test/scripting.coffee","test/undo-redo.coffee","test/utils.spec.coffee","test/validation.spec.coffee"],"names":[],"mappings":"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","sourcesContent":["keyDown = ($el, which) ->\n event = jQuery.Event(\"keydown\")\n event.which = which\n $el.trigger event\n \n event = jQuery.Event 'keyup'\n event.which = which\n $el.trigger event\n","describe 'Schemas with multiple types', ->\n it 'chooses the first one in the type list', ->\n tabKeyPress = ($el) -> keyDown($el, 9)\n\n schema = {\n type: 'array',\n items: {\n \"type\": [\n \"boolean\",\n \"integer\",\n \"number\",\n \"null\",\n \"string\"\n ]\n }\n }\n data = []\n \n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.addNewChild()\n newChild = treema.$el.find('.treema-node').data('instance')\n newChild.endExistingEdits()\n newChild.flushChanges()\n expect(treema.data[0]).toBe(false)\n ","describe 'Change callback', ->\n tabKeyPress = ($el) -> keyDown($el, 9)\n deleteKeyPress = ($el) -> keyDown($el, 8)\n\n fired = {}\n nameTreema = numbersTreema = tagsTreema = treema = null\n\n beforeEach ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n tags: { type: 'array', items: { type: 'string' } }\n }\n }\n data = {\n name: 'Bob',\n numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ],\n tags: ['Friend'],\n }\n \n treema = TreemaNode.make(null, {\n data: data\n schema: schema\n callbacks:\n change: ->\n console.log 'change callback', arguments\n fired.f += 1\n })\n treema.build()\n nameTreema = treema.childrenTreemas.name\n numbersTreema = treema.childrenTreemas.numbers\n tagsTreema = treema.childrenTreemas.tags\n fired.f = 0\n \n it 'fires when editing a field', ->\n valEl = nameTreema.getValEl()\n valEl.click()\n valEl.find('input').val('Boom').blur()\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you use set()', ->\n nameTreema.set('/', 'Foo')\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you use insert()', ->\n treema.insert('/numbers', {})\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you use delete()', ->\n treema.delete('/numbers/2') \n expect(fired.f).toBeGreaterThan(0)\n \n it 'does not fire when set() fails', ->\n nameTreema.set('/a/b/c/d/e', 'Foo')\n expect(fired.f).toBe(0)\n\n it 'does not fire when insert() fails', ->\n treema.insert('//a/b/c/d/e', {})\n expect(fired.f).toBe(0)\n\n it 'does not fire when delete() fails', ->\n treema.delete('//a/b/c/d/e')\n expect(fired.f).toBe(0)\n \n it 'fires when you add a new property to an object', ->\n treema.set('/blue', 'red')\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you add an object to an array', ->\n oldDataLength = numbersTreema.data.length\n numbersTreema.open()\n numbersTreema.$el.find('.treema-add-child').click()\n newDataLength = numbersTreema.data.length\n expect(oldDataLength).not.toBe(newDataLength)\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you add a non-collection to an array', ->\n tagsTreema.open()\n tagsTreema.$el.find('.treema-add-child').click()\n expect(fired.f).toBe(0)\n tabKeyPress(treema.$el.find('input').val('Star'))\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you delete an element in an array', ->\n tagsTreema.open()\n tagsTreema.$el.find('.treema-add-child').click()\n tabKeyPress(treema.$el.find('input').val('Star'))\n treema.endExistingEdits()\n tagTreema = tagsTreema.childrenTreemas[0]\n tagTreema.select()\n deleteKeyPress(treema.$el)\n expect(fired.f).toBeGreaterThan(0)\n\n it 'fires when you delete a property in an object', ->\n nameTreema.select()\n deleteKeyPress(treema.$el)\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires only once when you delete a selection of nodes', ->\n numbersTreema.open()\n numbersTreema.childrenTreemas[0].select()\n numbersTreema.childrenTreemas[1].shiftSelect()\n deleteKeyPress(treema.$el)\n expect(fired.f).toBe(1)\n ","describe 'defaults', ->\n \n it 'shows properties for object nodes which are specified in a default object that are not included in the data', ->\n data = { }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n expect(treema.childrenTreemas.key).toBeDefined()\n\n it 'does not put default data into the containing data object', ->\n data = { }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n expect(treema.data.key).toBeUndefined()\n\n it 'puts data into the containing data object when its value is changed', ->\n data = { }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.set('key', 'testValue')\n expect(treema.data.key).toBe('testValue')\n expect(treema.childrenTreemas.key.integrated).toBe(true)\n expect(treema.$el.find('.treema-node').length).toBe(1)\n \n it 'keeps a default node around when you delete one with backup default data', ->\n data = { key: 'setValue' }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.delete('key')\n expect(treema.data.key).toBeUndefined()\n expect(treema.childrenTreemas.key).toBeDefined()\n expect(treema.childrenTreemas.key.integrated).toBe(false)\n expect(Object.keys(treema.data).length).toBe(0)\n\n it 'integrates up the chain when setting an inner default value', ->\n data = { }\n schema = { default: { innerObject: { key1: 'value1', key2: 'value2' } } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.childrenTreemas.innerObject.open()\n treema.childrenTreemas.innerObject.childrenTreemas.key1.set('', 'newValue')\n expect(JSON.stringify(treema.data)).toBe(JSON.stringify({innerObject: {key1: 'newValue'}}))\n \n it 'takes defaultData from the make options', ->\n data = { }\n schema = { }\n treema = TreemaNode.make(null, {data: data, schema: schema, defaultData: { key: 'value' }})\n treema.build()\n expect(treema.childrenTreemas.key).toBeDefined()\n\n it 'does not set defaults just by opening a collection', ->\n data = { }\n schema = { default: { inventory: { prop1: 'test', prop2: 'test' } } }\n treema = TreemaNode.make(null, {data: data, schema: schema, defaultData: { key: 'value' }})\n treema.build()\n treema.open(2)\n expect($.isEmptyObject(treema.data)).toBe(true)\n","describe 'Children Filter', ->\n\t \n data = [\n {\n \"id\": \"0001\",\n \"type\": \"Donut\",\n \"name\": \"Cake\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n { \"id\": \"1002\", \"name\": \"Chocolate\" },\n { \"id\": \"1003\", \"name\": \"Blueberry\" },\n { \"id\": \"1004\", \"name\": \"Devil's Food\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5005\", \"name\": \"Sugar\" },\n { \"id\": \"5007\", \"name\": \"Powdered Sugar\" },\n { \"id\": \"5006\", \"name\": \"Chocolate with Sprinkles\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0002\",\n \"type\": \"Donut\",\n \"name\": \"Raised\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5005\", \"name\": \"Sugar\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0001\",\n \"type\": \"Donut\",\n \"name\": \"Cake 2\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n { \"id\": \"1002\", \"name\": \"Chocolate\" },\n { \"id\": \"1003\", \"name\": \"Blueberry\" },\n { \"id\": \"1004\", \"name\": \"Devil's Food\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5005\", \"name\": \"Sugar\" },\n { \"id\": \"5007\", \"name\": \"Powdered Sugar\" },\n { \"id\": \"5006\", \"name\": \"Chocolate with Sprinkles\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0003\",\n \"type\": \"Donut\",\n \"name\": \"Old Fashioned\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n { \"id\": \"1002\", \"name\": \"Chocolate\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0004\",\n \"type\": \"Pastry\",\n \"name\": \"Croissant\",\n \"ppu\": 2.95,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n ]\n }\n ]\n\n schema = {\n type: 'array',\n items: {\n \"additionalProperties\": false,\n \"type\": \"object\",\n \"format\": \"product\",\n \"displayProperty\": 'name',\n \"properties\": {\n \"id\": { title: \"ID\", type: \"string\" },\n \"name\": { title: \"Name\", type: \"string\", maxLength: 20 },\n \"type\": { title: \"Product Type\", type: \"string\", enum: ['Donut', 'Pastry']},\n \"ppu\": { title: \"Price\", type: \"number\", format: \"price\"},\n \"batters\": {\n type: \"array\",\n title: \"Batter Options\",\n uniqueItems: true,\n maxItems: 4,\n items: {\n type: \"object\",\n format: \"batter\",\n properties: {\n \"id\": { type:\"string\" },\n \"type\": { type:\"string\" }\n }\n }\n },\n \"toppings\": {\n type: \"array\",\n title: \"Topping Options\",\n uniqueItems: true,\n maxItems: 7,\n items: {\n type: \"object\",\n format: \"topping\",\n properties: {\n \"id\": { type:\"string\" },\n \"type\": { type:\"string\" }\n }\n }\n }\n }\n }\n }\n\n treemaFilterHiddenClass = 'treema-filter-hidden'\n el = $('')\n treema = TreemaNode.make(el, {data: data, schema: schema})\n treema.build()\n\n createTitleFilter = (text)->\n \tfilter = (treemaNode, keyForParent)->\n \t return !text or text.trim() == '' or treemaNode.getValEl().text().toLowerCase().indexOf(text.toLowerCase()) >= 0\n return filter\n\n it 'Filter node on node title', ->\n\n treema.filterChildren(createTitleFilter(''))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(5)\n treema.clearFilter\n\n treema.filterChildren(createTitleFilter('cake'))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(2)\n treema.clearFilter\n\n treema.filterChildren(createTitleFilter('OLD fashioned'))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(1)\n treema.clearFilter\n\n treema.filterChildren(createTitleFilter('@@'))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(0)\n treema.clearFilter\n\n it 'Nodes are always visible on null filter', ->\n treema.filterChildren(null)\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(5)\n treema.clearFilter\n\n treema.filterChildren(undefined)\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(5)\n treema.clearFilter\n\n describe 'Navigate nodes using keyboard should skip hidden nodes', =>\n \n @firstTreema = $(el).find('.treema-node').eq(0).data('instance')\n @thirdTreema = $(el).find('.treema-node').eq(2).data('instance')\n\n @leftArrowPress = ($el) -> keyDown($el, 37)\n @upArrowPress = ($el) -> keyDown($el, 38)\n @rightArrowPress = ($el) -> keyDown($el, 39)\n @downArrowPress = ($el) -> keyDown($el, 40)\n\n \tit 'Select the first node.', =>\n @firstTreema.select()\n expect(@firstTreema.isSelected()).toBe(true)\n\n it 'Navigate to next node. The node is expected to be the third node, since the second node is hidden by filter', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.navigateSelection(1)\n expect(@thirdTreema.isSelected()).toBe(true)\n treema.clearFilter\n \n it 'Navigate back to previous node, the first node', =>\n treema.filterChildren(createTitleFilter('cake'))\n @thirdTreema.navigateSelection(-1)\n expect(@firstTreema.isSelected()).toBe(true)\n treema.clearFilter\n \n it 'Cyclic Navigation', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.navigateSelection(-1)\n @firstTreema.navigateSelection(-1)\n expect(@firstTreema.isSelected()).toBe(true)\n treema.clearFilter\n \n it 'When a node is open, the next node becomes its first child node', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.open()\n @firstTreema.navigateSelection(1)\n\n @firstChildren = @firstTreema.getNodeEl().find('.treema-children').children().eq(0).data('instance')\n @secondChildren = @firstTreema.getNodeEl().find('.treema-children').children().eq(1).data('instance')\n\n expect(@firstChildren.isSelected()).toBe(true)\n @firstChildren.navigateSelection(1)\n expect(@secondChildren.isSelected()).toBe(true)\n\n @firstTreema.close()\n treema.clearFilter\n \n it 'Simulate arrow key press', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.select()\n\n @downArrowPress(el) \n expect(@thirdTreema.isSelected()).toBe(true)\n\n @upArrowPress(el) \n expect(@firstTreema.isSelected()).toBe(true)\n\n treema.clearFilter","describe 'TreemaNode.delete', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'removes objects from an array', ->\n expect(treema.delete('/numbers/0')).toBeTruthy()\n numbers = treema.get('/numbers')\n expect(numbers.length).toBe(1)\n expect(numbers[0].type).toBe('Work')\n \n it 'removes properties from an object', ->\n expect(treema.delete('/numbers/0/type')).toBeTruthy()\n expect(treema.get('/numbers').type).toBeUndefined()\n expect(treema.get('/numbers/type')).toBeUndefined()\n","describe 'TreemaNode.get', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n \n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n\n it 'gets immediate values', ->\n expect(treema.get('/name')).toBe('Bob')\n \n it 'can search on object keys within an array', ->\n expect(treema.get('/numbers/type=Work').number).toBe('123-456-7890')\n \n it 'can start from a child', ->\n expect(nameTreema.get('/')).toBe('Bob')\n \n it 'returns undefined for invalid paths', ->\n expect(treema.get('waffles')).toBeUndefined()\n ","describe 'TreemaNode.insert', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'appends data to the end of an array', ->\n expect(treema.insert('/numbers', {'number':'4321'})).toBeTruthy()\n numbers = treema.get('/numbers')\n expect(numbers.length).toBe(3)\n expect(numbers[2].number).toBe('4321')\n\n it 'returns false for paths that are not arrays', ->\n expect(treema.insert('/numbers/0', 'boom')).toBeFalsy()\n \n it 'returns false for paths that do not exist', ->\n expect(treema.insert('/numbahs', 'boom')).toBeFalsy()","describe 'TreemaNode.set', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'sets immediate values', ->\n expect(treema.set('/name', 'Bobby')).toBeTruthy()\n expect(treema.get('/name')).toBe('Bobby')\n \n it 'can search an object within an array', ->\n expect(treema.set('/numbers/type=Home/number', '1234')).toBeTruthy()\n expect(treema.get('/numbers/type=Home/number')).toBe('1234')\n \n it 'can set new properties', ->\n expect(treema.set('/numbers/0/daytime', true)).toBeTruthy()\n expect(treema.get('/numbers/0/daytime')).toBe(true)\n \n it 'updates the visuals of the node and all its parents', ->\n treema.childrenTreemas.numbers.open()\n treema.childrenTreemas.numbers.childrenTreemas[0].open()\n expect(treema.set('/numbers/0/type', 'Cell')).toBeTruthy()\n t = treema.childrenTreemas.numbers.$el.find('> .treema-row > .treema-value').text()\n expect(t.indexOf('Home')).toBe(-1)\n\n it 'affects the base data', ->\n expect(treema.data['numbers'][0]['daytime']).toBe(true)","describe 'Initialization', ->\n\n schema = { type: 'object', properties: { name: { type: 'string', 'default': 'Untitled'} } }\n data = { }\n el = $('')\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n\n it 'creates an $el if none is given', ->\n expect(treema.$el).toBeDefined()\n\n it 'uses the jQuery element given', ->\n elTreema = TreemaNode.make(el, {data: data, schema: schema})\n expect(elTreema.$el).toBe(el)\n\n# it 'grabs default data from an object schema', ->\n# noDataTreema = TreemaNode.make(null, {schema: schema})\n# expect(noDataTreema.data.name).toBe('Untitled')\n\n it 'opens up root collection nodes by default', ->\n treema.build()\n expect(treema.isOpen()).toBeTruthy()\n\ndescribe 'Schemaless', ->\n\n schema = type: 'object'\n data =\n errors: []\n warnings: [\n {\n hint: undefined\n userInfo: {}\n id: \"jshint_W099\"\n message: \"Mixed spaces and tabs.\"\n level: \"warning\"\n type: \"transpile\"\n ranges: [[[8, 0], [8, 3]]]\n }\n ]\n infos: []\n el = $('')\n treema = TreemaNode.make(el, {data: data, schema: schema})\n\n it 'initializes when given data for an empty schema', ->\n expect(treema.$el).toBeDefined()","do ->\n leftArrowPress = ($el) -> keyDown($el, 37)\n upArrowPress = ($el) -> keyDown($el, 38)\n rightArrowPress = ($el) -> keyDown($el, 39)\n downArrowPress = ($el) -> keyDown($el, 40)\n \n expectOneSelected = (t) ->\n selected = treema.getSelectedTreemas()\n expect(selected.length).toBe(1)\n expect(t).toBeDefined()\n expect(selected[0].$el[0]).toBe(t.$el[0]) if t and selected.length is 1 \n\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: ['string', 'array'] } }\n address: { type: 'string' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', ['123-456-7890']], 'address': 'Mars' }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n addressTreema = treema.childrenTreemas.address\n \n beforeEach ->\n treema.deselectAll()\n phoneTreema.close()\n \n describe 'Down arrow key press', ->\n it 'selects the top row if nothing is selected', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n downArrowPress(treema.$el)\n expect(nameTreema.isSelected()).toBeTruthy()\n \n it 'skips past closed collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n downArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n downArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n downArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n \n it 'traverses open collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n phoneTreema.open()\n downArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n downArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n downArrowPress(treema.$el)\n expectOneSelected(phoneTreema.childrenTreemas[0])\n# downArrowPress(treema.$el)\n# expectOneSelected(phoneTreema.childrenTreemas[1])\n# downArrowPress(treema.$el)\n# expectOneSelected(addressTreema)\n \n it 'does nothing if the last treema is selected', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n addressTreema.select()\n expectOneSelected(addressTreema)\n downArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n\n describe 'Up arrow key press', ->\n it 'selects the bottom row if nothing is selected', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n upArrowPress(treema.$el)\n expect(addressTreema.isSelected()).toBeTruthy()\n\n it 'skips past closed collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n upArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n upArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n\n it 'traverses open collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n phoneTreema.open()\n upArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema.childrenTreemas[1])\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema.childrenTreemas[0])\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n upArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n\n it 'wraps around if the first treema is selected', ->\n nameTreema.select()\n expectOneSelected(nameTreema)\n upArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n\n describe 'Right arrow key press', ->\n it 'does nothing if the selected row isn\\'t a collection', ->\n nameTreema.select()\n expectOneSelected(nameTreema)\n rightArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n \n it 'opens a collection if a collection is selected', ->\n expect(phoneTreema.isClosed()).toBeTruthy()\n phoneTreema.select()\n rightArrowPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema)\n \n describe 'Left arrow key press', ->\n it 'closes an open, selected collection', ->\n phoneTreema.open()\n phoneTreema.select()\n leftArrowPress(treema.$el)\n expect(phoneTreema.isClosed()).toBeTruthy()\n expectOneSelected(phoneTreema)\n \n it 'closes the selection if it can be closed, otherwise moves the selection up a level', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].select()\n leftArrowPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema)\n leftArrowPress(treema.$el)\n expect(phoneTreema.isClosed()).toBeTruthy()\n expectOneSelected(phoneTreema)\n \n it 'affects one collection at a time, deepest first', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].open()\n phoneTreema.childrenTreemas[1].childrenTreemas[0].select()\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.childrenTreemas[1].isOpen()).toBeTruthy()\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema.childrenTreemas[1])\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.childrenTreemas[1].isClosed()).toBeTruthy()\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema.childrenTreemas[1])\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema)\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.isClosed()).toBeTruthy()\n expectOneSelected(phoneTreema)","describe 'Delete key press', ->\n deleteKeyPress = ($el) -> keyDown($el, 8)\n\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: ['string', 'array'] } }\n address: { type: 'string' }\n }\n }\n original_data = { name: 'Bob', numbers: ['401-401-1337', ['123-456-7890']], 'address': 'Mars' }\n treema = nameTreema = addressTreema = phoneTreema = null\n \n rebuild = ->\n copy = $.extend(true, {}, original_data)\n treema = TreemaNode.make(null, {data: copy, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n addressTreema = treema.childrenTreemas.address\n phoneTreema = treema.childrenTreemas.numbers\n\n expectOneSelected = (t) ->\n selected = treema.getSelectedTreemas()\n expect(selected.length).toBe(1)\n expect(selected[0]).toBe(t)\n\n beforeEach ->\n rebuild()\n \n it 'does nothing when nothing is selected', ->\n deleteKeyPress(treema.$el)\n expect(treema.data.name).toBe(original_data.name)\n expect(treema.data.address).toBe(original_data.address)\n \n it 'removes a selected row', ->\n nameTreema.select()\n deleteKeyPress(treema.$el)\n expect(treema.data.name).toBeUndefined()\n expect(treema.childrenTreemas.name).toBeUndefined()\n expect(treema.childrenTreemas.address).toBeTruthy()\n \n it 'removes all selected rows', ->\n nameTreema.select()\n addressTreema.toggleSelect()\n deleteKeyPress(treema.$el)\n expect(treema.data.name).toBeUndefined()\n expect(treema.data.address).toBeUndefined()\n expect(treema.childrenTreemas.name).toBeUndefined()\n expect(treema.childrenTreemas.address).toBeUndefined()\n\n it 'removes single elements of a collection one at a time, then the collection itself', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].open()\n phoneTreema.childrenTreemas[0].select()\n expect(treema.data.numbers.length).toBe(2)\n\n # deletes '401...', selects ['123...'] (which is now at index 0)\n # stays at the same level, does not enter the open collection\n deleteKeyPress(treema.$el)\n expect(treema.data.numbers.length).toBe(1)\n expectOneSelected(phoneTreema.childrenTreemas[0])\n\n # deletes ['123...'], selects numbers\n # when there are no more elements, goes to the parent\n deleteKeyPress(treema.$el)\n expect(treema.data.numbers.length).toBe(0)\n expectOneSelected(phoneTreema)\n\n # deletes numbers, selects address\n # when there's an element the one just deleted, it goes down\n deleteKeyPress(treema.$el) \n expect(treema.data.numbers).toBeUndefined()\n expectOneSelected(addressTreema)\n\n # deletes address, selects name\n # when there's no element after the one just deleted, it goes up\n deleteKeyPress(treema.$el) \n expect(treema.data.address).toBeUndefined()\n expectOneSelected(nameTreema)\n\n # deletes name, nothing more to select\n # when there are no more elements, select nothing\n deleteKeyPress(treema.$el) \n expect(treema.data.name).toBeUndefined()\n expect(treema.getSelectedTreemas().length).toBe(0)\n expect(Object.keys(treema.data).length).toBe(0)\n \n it 'removes a row if it\\'s being edited and there\\'s nothing in the focused input', ->\n nameTreema.edit()\n nameTreema.$el.find('input').val('')\n deleteKeyPress(nameTreema.$el.find('input'))\n expect(treema.data.name).toBeUndefined()\n expectOneSelected(phoneTreema)\n\n it 'performs normally if a focused input has value', ->\n nameTreema.edit()\n deleteKeyPress(nameTreema.$el.find('input'))\n expect(treema.data.name).toBeTruthy()\n","describe 'Enter key press', ->\n enterKeyPress = ($el) -> keyDown($el, 13)\n\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'string', minLength: 4 } }\n address: { type: 'string' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890'], 'address': 'Mars' }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n \n afterEach ->\n treema.endExistingEdits()\n phoneTreema.close()\n \n it 'edits the last selected row', ->\n nameTreema.select()\n enterKeyPress(treema.$el)\n expect(nameTreema.isEditing()).toBeTruthy()\n \n it 'saves the current row and goes on to the next value in the collection if there is one', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('4321')\n enterKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[0].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('4321')\n \n it 'traverses into and out of open collections', ->\n phoneTreema.open()\n nameTreema.edit()\n enterKeyPress(nameTreema.$el)\n expect(phoneTreema.isSelected()).toBeTruthy()\n enterKeyPress(treema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n enterKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n \n it 'opens closed collections', ->\n phoneTreema.select()\n enterKeyPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n \n it 'shows errors and moves on when saving an invalid row', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('1')\n enterKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[0].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('1')\n expect(treema.isValid()).toBeFalsy()\n\n it 'goes backwards if shift is pressed', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].edit()\n\n event = jQuery.Event(\"keydown\")\n event.which = 13\n event.shiftKey = true\n phoneTreema.childrenTreemas[1].$el.trigger(event)\n\n expect(phoneTreema.childrenTreemas[1].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n \n it 'edits the first child in a collection if a collection is selected', ->\n phoneTreema.open()\n phoneTreema.select()\n enterKeyPress(phoneTreema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n","describe '\"N\" key press', ->\n nKeyPress = ($el) -> keyDown($el, 78)\n enterKeyPress = ($el) -> keyDown($el, 13)\n\n schema = {\n type: 'array',\n maxItems: 3,\n items: { type: 'string' }\n }\n data = ['401-401-1337', '123-456-7890']\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'creates a new row for the currently selected collection', ->\n treema.childrenTreemas[0].select()\n expect(treema.childrenTreemas[2]).toBeUndefined()\n nKeyPress(treema.childrenTreemas[0].$el)\n expect(treema.childrenTreemas[2]).toBeUndefined()\n enterKeyPress(treema.$el.find('input').val('410-555-1023'))\n expect(treema.childrenTreemas[2]).not.toBeUndefined()\n treema.childrenTreemas[2].display()\n treema.childrenTreemas[2].select()\n expect(treema.childrenTreemas[2]).not.toBeUndefined()\n \n it 'does not create a new row when there\\'s no more space', ->\n expect(treema.data.length).toBe(3)\n nKeyPress(treema.childrenTreemas[0].$el)\n expect(treema.data.length).toBe(3)","# almost exactly the same as enter, except it keeps focus on a row that is invalid\n\ndescribe 'Tab key press', ->\n tabKeyPress = ($el) -> keyDown($el, 9)\n \n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'string', minLength: 4 } }\n address: { type: 'string' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890'], 'address': 'Mars' }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n addressTreema = treema.childrenTreemas.address\n \n afterEach ->\n treema.endExistingEdits()\n phoneTreema.close()\n \n it 'edits the last selected row', ->\n nameTreema.select()\n tabKeyPress(treema.$el)\n expect(nameTreema.isEditing()).toBeTruthy()\n\n it 'saves the current row and goes on to the next value in the collection if there is one', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('4321')\n tabKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[0].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('4321')\n\n it 'traverses into and out of open collections', ->\n phoneTreema.open()\n nameTreema.edit()\n tabKeyPress(nameTreema.$el)\n expect(phoneTreema.isSelected()).toBeTruthy()\n tabKeyPress(treema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n tabKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n\n it 'skips over closed collections', ->\n nameTreema.edit()\n tabKeyPress(nameTreema.$el)\n expect(phoneTreema.isSelected()).toBeTruthy()\n tabKeyPress(treema.$el)\n expect(addressTreema.isEditing()).toBeTruthy()\n\n it 'shows errors and stays put when saving an invalid row', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('1')\n tabKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[1].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('1')\n expect(treema.isValid()).toBeFalsy()\n\n it 'goes backwards if shift is pressed', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].edit()\n\n event = jQuery.Event(\"keydown\")\n event.which = 9\n event.shiftKey = true\n phoneTreema.childrenTreemas[1].$el.trigger(event)\n\n expect(phoneTreema.childrenTreemas[1].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n\n it 'edits the first child in a collection if a collection is selected', ->\n phoneTreema.open()\n phoneTreema.select()\n tabKeyPress(phoneTreema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n","describe 'Mouse click behavior', ->\n\n treema = nameTreema = phoneTreema = null\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'string' } }\n }\n }\n \n beforeEach ->\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890'] }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n \n shiftClick = ($el) ->\n event = jQuery.Event(\"click\")\n event.shiftKey = true\n $el.trigger(event)\n \n metaClick = ($el) ->\n event = jQuery.Event(\"click\")\n event.metaKey = true\n $el.trigger(event)\n \n it 'starts editing if you click the value', ->\n expect(nameTreema.isDisplaying()).toBe(true)\n nameTreema.$el.find('.treema-value').click()\n expect(nameTreema.isEditing()).toBe(true)\n \n it 'opens a collection if you click the value', ->\n expect(phoneTreema.isClosed()).toBe(true)\n phoneTreema.$el.find('.treema-value').click()\n expect(phoneTreema.isOpen()).toBe(true)\n \n it 'selects and unselects the row if you click something other than the value', ->\n expect(nameTreema.isSelected()).toBe(false)\n nameTreema.$el.click()\n expect(nameTreema.isSelected()).toBe(true)\n nameTreema.$el.click()\n expect(nameTreema.isSelected()).toBe(false)\n\n it 'selects along all open rows if you shift click', ->\n phoneTreema.open()\n nameTreema.$el.click()\n shiftClick(phoneTreema.childrenTreemas[0].$el)\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(true)\n expect(phoneTreema.childrenTreemas[0].isSelected()).toBe(true)\n expect(phoneTreema.childrenTreemas[1].isSelected()).toBe(false)\n \n it 'keeps the clicked row selected if there are multiple selections to begin with', ->\n nameTreema.$el.click()\n shiftClick(phoneTreema.$el)\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(true)\n nameTreema.$el.click()\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(false)\n \n it 'toggles the select state if you ctrl/meta click', ->\n nameTreema.$el.click()\n metaClick(phoneTreema.$el)\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(true)\n metaClick(nameTreema.$el)\n expect(nameTreema.isSelected()).toBe(false)\n expect(phoneTreema.isSelected()).toBe(true)\n","describe 'readOnly in schema', ->\n\n schema = {\n type: 'object',\n properties: {\n name: { \n type: 'string',\n readOnly: true\n },\n\n numbers: { \n type: 'array', \n items: { type: 'object' }, \n readOnly: true \n },\n \n tags: {\n type: 'array',\n items: { type: 'string', readOnly: true } \n },\n \n tags2: {\n type: 'array',\n items: { type: 'string' },\n readOnly: true\n }\n\n map: {\n type: 'object',\n readOnly: true\n }\n }\n }\n data = {\n name: 'Bob',\n numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ],\n tags: ['Friend'],\n tags2: ['Friend'],\n map: {\n 'string': 'String',\n 'object': { 'key': 'value' }\n }\n }\n \n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'prevents editing of readOnly non-collection properties', ->\n expect(treema.childrenTreemas.name.canEdit()).toBe(false)\n \n # arrays\n \n it 'prevents removing from readOnly arrays', ->\n treema.childrenTreemas.numbers.remove()\n expect(treema.data.numbers).not.toBeUndefined()\n \n it 'prevents adding items to readOnly arrays', ->\n expect(treema.childrenTreemas.numbers.canAddChild()).toBe(false)\n \n it 'prevents removing readOnly items from arrays which are not readOnly', ->\n treema.childrenTreemas.tags.open()\n treema.childrenTreemas.tags.childrenTreemas[0].remove()\n expect(treema.data.tags.length).toBe(1)\n \n it 'prevents editing non-collection items in readOnly arrays', ->\n treema.childrenTreemas.tags2.open()\n expect(treema.childrenTreemas.tags2.childrenTreemas[0].canEdit()).toBe(false)\n \n # objects\n\n it 'prevents removing from readOnly objects', ->\n treema.childrenTreemas.map.remove()\n expect(treema.data.map).not.toBeUndefined()\n\n it 'prevents adding to readOnly objects', ->\n expect(treema.childrenTreemas.map.canAddChild()).toBe(false)\n\n it 'prevents removing readOnly properties from objects which are not readOnly', ->\n treema.childrenTreemas.name.remove()\n treema.childrenTreemas.tags.childrenTreemas[0].remove()\n expect(treema.data.tags.length).toBe(1)\n\n it 'prevents editing non-collection properties in readOnly objects', ->\n treema.childrenTreemas.map.open()\n expect(treema.childrenTreemas.map.childrenTreemas.string.canEdit()).toBe(false)\n \n","describe 'schema property \"required\"', ->\n treema = null\n beforeEach ->\n schema = {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"0\": { type: \"integer\" },\n \"1\": { type: \"string\" },\n \"2\": { type: \"number\" },\n \"3\": { type: \"null\" },\n \"4\": { type: \"boolean\" },\n \"5\": { type: \"array\", items: { type: 'number', default: 42 } },\n \"6\": { type: \"object\" },\n \"7\": { 'default': 1337 }\n },\n \"required\": ['0', '1', '2', '3','4','5','6','7']\n }\n data = {}\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'populates all required values with generic data', ->\n expect(treema.get('/0')).toBe(0)\n expect(treema.get('/1')).toBe('')\n expect(treema.get('/2')).toBe(0)\n expect(treema.get('/3')).toBe(null)\n expect(treema.get('/4')).toBe(false)\n expect(JSON.stringify(treema.get('/5'))).toBe(JSON.stringify([]))\n expect(JSON.stringify(treema.get('/6'))).toBe(JSON.stringify({}))\n\n it 'populates required values with defaults', ->\n expect(treema.get('/7')).toBe(1337)\n treema.childrenTreemas['5'].addNewChild()\n expect(treema.$el.find('input').val()).toBe('42')\n \ndescribe 'schema property \"required\"', ->\n it 'populates data from the object\\'s default property', ->\n schema =\n type: 'object'\n default: { key1: 'object default' }\n required: ['key1']\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key1).toBe('object default')\n\n it 'populates data based on the child schema type', ->\n schema =\n type: 'object'\n required: ['key2']\n properties:\n key2: { type: 'number' }\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key2).toBe(0)\n\n it 'populates data from the child schema\\'s default property', ->\n schema =\n type: 'object'\n required: ['key3']\n properties:\n key3: { default: 'inner default' }\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key3).toBe('inner default')\n\n it 'populates data as an empty string if nothing else is available', ->\n schema =\n required: ['key4']\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key4).toBe('')\n","do ->\n expectOpen = (t) ->\n expect(t).toBeDefined()\n expect(t.isClosed()).toBeFalsy()\n\n expectClosed = (t) ->\n expect(t).toBeDefined()\n expect(t.isClosed()).toBeTruthy()\n\n schema =\n type: 'object',\n properties:\n name:\n type: 'string'\n info:\n type: 'object'\n properties:\n numbers:\n type: 'array',\n items:\n type: ['string', 'array']\n data = name: 'Thor', info: {numbers: ['401-401-1337', ['123-456-7890']]}\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n beforeEach ->\n treema.deselectAll()\n treema.close()\n\n describe 'open', ->\n it 'can open n levels deep', ->\n expectClosed(treema)\n treema.open(2)\n expectOpen(treema)\n infoTreema = treema.childrenTreemas.info\n expectOpen(infoTreema)\n phoneTreema = infoTreema.childrenTreemas.numbers\n expectClosed(phoneTreema)\n","describe 'Undo-redo behavior', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: ['string', 'array'] } }\n address: { type: 'string' }\n completed: { type: 'boolean' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890', '456-7890-123'], address: 'Mars', completed: false }\n originalData = jQuery.extend(true, {}, data)\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n numbersTreema = treema.childrenTreemas.numbers\n addressTreema = treema.childrenTreemas.address\n completedTreema = treema.childrenTreemas.completed\n\n it 'does nothing when there are no actions to be undone', ->\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.data).toEqual(originalData)\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n # Edit actions---------------------------------------------------------------------\n it 'reverts a set object property', ->\n path = '/name'\n treema.set '/name', 'Alice'\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get(path)).toEqual('Alice')\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n it 'reverts a set array element', ->\n path = '/numbers/1'\n treema.set path, '1'\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get(path)).toEqual('1')\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n it 'reverts a toggled boolean value', ->\n completedTreema.toggleValue()\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get('/completed')).toBe(true)\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n # Insert actions---------------------------------------------------------------------\n it 'reverts an element inserted into an array', ->\n path = '/numbers'\n treema.insert path, '1' \n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n numbersData = treema.get path\n expect(numbersData[numbersData.length-1]).toEqual('1')\n treema.set '/', jQuery.extend(true, {}, originalData)\n \n # Delete actions----------------------------------------------------------------------\n it 'reverts a deleted object property', ->\n path = '/name'\n treema.delete path\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get(path)).toBe(undefined)\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n it 'reverts a element deleted from the middle of an array', ->\n path = '/numbers/1'\n treema.delete path\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.data).toNotEqual(originalData)\n treema.set '/', jQuery.extend(true, {}, originalData) \n\n #Combinations of actions\n it 'reverts a series of edit, insert and delete actions', ->\n treema.set '/name', 'Alice'\n treema.insert '/numbers', '1'\n treema.delete '/numbers'\n\n treema.undo()\n expect(treema.get('/numbers')).toBeDefined()\n treema.undo()\n expect(treema.get('/numbers')).toEqual(numbersTreema.data)\n treema.undo()\n expect(treema.data).toEqual(originalData)\n\n treema.redo()\n expect(treema.get('/name')).toBe('Alice')\n treema.redo()\n numbersData = treema.get '/numbers'\n expect(numbersData[numbersData.length-1]).toEqual('1')\n treema.redo()\n expect(treema.get('/numbers')).toBeUndefined()\n","describe 'utilities', ->\n backupJQuery = $\n \n beforeEach ->\n window.jQuery = undefined\n window.$ = undefined\n \n afterEach ->\n window.jQuery = backupJQuery\n window.$ = backupJQuery\n \n describe 'tests', ->\n it 'run in an environment without jQuery', ->\n hadError = false\n try\n $('body')\n catch\n hadError = true\n expect(hadError).toBe(true)\n \n describe 'populateDefaults', ->\n it 'walks through data and applies schema defaults to data', ->\n schema = {\n type: 'object'\n default: { innerObject: {}, someProp: 1 }\n properties:\n innerObject: { default: { key1: 'value1', key2: 'value2' }}\n }\n \n data = null\n \n result = TreemaNode.utils.populateDefaults(data, schema)\n \n expect(result).toBeDefined()\n expect(result.innerObject).toBeDefined()\n expect(result.innerObject.key1).toBe('value1')\n expect(result.innerObject.key2).toBe('value2')\n \n it 'merges in default objects that are adjacent to extant data', ->\n schema = {\n type: 'object'\n properties:\n innerObject: { default: { key1: 'value1', key2: 'value2' }}\n }\n\n data = { innerObject: { key1: 'extantData' }}\n\n result = TreemaNode.utils.populateDefaults(data, schema)\n\n expect(result).toBeDefined()\n expect(result.innerObject).toBeDefined()\n expect(result.innerObject.key1).toBe('extantData')\n expect(result.innerObject.key2).toBe('value2')\n\n \n # In order to support the default structure below, would need to\n # make populateData a bit more complicated, with some custom merging logic.\n # Going to see if we can get away without it first.\n \n# it 'merges default objects from parent schemas down to child extant data', ->\n# schema = {\n# type: 'object'\n# default: { innerObject: { key1: 'value1', key2: 'value2' } }\n# }\n#\n# data = { innerObject: { prop1: 'extantData' } }\n#\n# result = TreemaNode.utils.populateDefaults(data, schema)\n#\n# expect(result.innerObject).toBeDefined()\n# expect(result.innerObject.prop1).toBe('extantData')\n# expect(result.innerObject.prop2).toBe('2')\n \n describe 'walk', ->\n it 'calls a callback on every piece of data in a JSON object, providing path, data and working schema', ->\n schema = {\n type: 'object'\n properties:\n key1: { title: 'Number 1' }\n key2: { title: 'Number 2' }\n }\n \n data = { key1: 1, key2: 2 }\n \n paths = []\n values = []\n \n TreemaNode.utils.walk data, schema, null, (path, data, schema) ->\n paths.push(path)\n values.push(data)\n \n expect(paths.length).toBe(3)\n \n expect('' in paths).toBe(true)\n expect('key1' in paths).toBe(true)\n expect('key2' in paths).toBe(true)\n \n expect(data in values).toBe(true)\n expect(data.key1 in values).toBe(true)\n expect(data.key2 in values).toBe(true)\n \n describe 'getChildSchema', ->\n it 'returns child schemas from properties', ->\n schema = { properties: { key1: { title: 'some title' } }}\n childSchema = TreemaNode.utils.getChildSchema('key1', schema)\n expect(childSchema.title).toBe('some title')\n \n it 'returns child schemas from additionalProperties', ->\n schema = { additionalProperties: { title: 'some title' } }\n childSchema = TreemaNode.utils.getChildSchema('key1', schema)\n expect(childSchema.title).toBe('some title')\n \n it 'returns child schemas from patternProperties', ->\n schema = { patternProperties: { '^[a-z]+$': { title: 'some title' } }}\n childSchema = TreemaNode.utils.getChildSchema('key', schema)\n expect(childSchema.title).toBe('some title')\n childSchema = TreemaNode.utils.getChildSchema('123', schema)\n expect(childSchema.title).toBeUndefined()\n\n it 'returns child schemas from an items schema', ->\n schema = { items: { title: 'some title' } }\n childSchema = TreemaNode.utils.getChildSchema(0, schema)\n expect(childSchema.title).toBe('some title')\n\n it 'returns child schemas from an items array of schemas', ->\n schema = { items: [{ title: 'some title' }] }\n childSchema = TreemaNode.utils.getChildSchema(0, schema)\n expect(childSchema.title).toBe('some title')\n childSchema = TreemaNode.utils.getChildSchema(1, schema)\n expect(childSchema.title).toBeUndefined()\n \n it 'returns child schemas from additionalItems', ->\n schema = { items: [{ title: 'some title' }], additionalItems: { title: 'another title'} }\n childSchema = TreemaNode.utils.getChildSchema(1, schema)\n expect(childSchema.title).toBe('another title')\n\n describe 'buildWorkingSchemas', ->\n it 'returns the same single schema if there are no combinatorials or references', ->\n schema = {}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas[0] is schema).toBeTruthy()\n \n it 'combines allOf into a single schema', ->\n schema = { title: 'title', allOf: [ { description: 'description' }, { type: 'number' } ]}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas.length).toBe(1)\n workingSchema = workingSchemas[0]\n expect(workingSchema.title).toBe('title')\n expect(workingSchema.description).toBe('description')\n expect(workingSchema.type).toBe('number')\n \n it 'creates a separate working schema for each anyOf', ->\n schema = { title: 'title', anyOf: [{ type: 'string' }, { type: 'number' }]}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas.length).toBe(2)\n types = (schema.type for schema in workingSchemas)\n expect('string' in types).toBe(true)\n expect('number' in types).toBe(true)\n\n it 'creates a separate working schema for each oneOf', ->\n schema = { title: 'title', oneOf: [{ type: 'string' }, { type: 'number' }]}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas.length).toBe(2)\n types = (schema.type for schema in workingSchemas)\n expect('string' in types).toBe(true)\n expect('number' in types).toBe(true)\n \n # Eventually might want more advanced behaviors, like smartly combining types from \"allOf\" or \"oneOf\" schemas.\n # But for now this more naive combination behavior will do.","describe 'showing errors', ->\n it 'does not go away when you close and open a collection', ->\n schema = {\n type: 'object',\n additionalProperties: false\n }\n data = { someProp: ['test', 1, 2, 3] }\n\n treema = $('').treema({ schema:schema, data:data })\n treema.build()\n expect(treema.$el.find('.treema-error').length).toBe(1)\n window.treema = treema\n treema.childrenTreemas.someProp.open()\n expect(treema.$el.find('.treema-error').length).toBe(1)\n treema.childrenTreemas.someProp.close()\n expect(treema.$el.find('.treema-error').length).toBe(1)\n"]} \ No newline at end of file +{"version":3,"sources":["test/common.coffee","test/ambiguous/type.coffee","test/callbacks/change.coffee","test/canAddProperty.spec.coffee","test/default.spec.coffee","test/filter.coffee","test/getters-setters/delete.coffee","test/getters-setters/get.coffee","test/getters-setters/insert.coffee","test/getters-setters/set.coffee","test/initialization.coffee","test/keyboard/arrow-keys.coffee","test/keyboard/delete-key.coffee","test/keyboard/enter-key.coffee","test/keyboard/n-key.coffee","test/keyboard/tab-key.coffee","test/mouse-click.coffee","test/readOnly.coffee","test/required.spec.coffee","test/scripting.coffee","test/undo-redo.coffee","test/utils.spec.coffee","test/validation.spec.coffee"],"names":[],"mappings":"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","file":"dev/js/treema.spec.js","sourcesContent":["keyDown = ($el, which) ->\n event = jQuery.Event(\"keydown\")\n event.which = which\n $el.trigger event\n \n event = jQuery.Event 'keyup'\n event.which = which\n $el.trigger event\n","describe 'Schemas with multiple types', ->\n it 'chooses the first one in the type list', ->\n tabKeyPress = ($el) -> keyDown($el, 9)\n\n schema = {\n type: 'array',\n items: {\n \"type\": [\n \"boolean\",\n \"integer\",\n \"number\",\n \"null\",\n \"string\"\n ]\n }\n }\n data = []\n \n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.addNewChild()\n newChild = treema.$el.find('.treema-node').data('instance')\n newChild.endExistingEdits()\n newChild.flushChanges()\n expect(treema.data[0]).toBe(false)\n ","describe 'Change callback', ->\n tabKeyPress = ($el) -> keyDown($el, 9)\n deleteKeyPress = ($el) -> keyDown($el, 8)\n\n fired = {}\n nameTreema = numbersTreema = tagsTreema = treema = null\n\n beforeEach ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n tags: { type: 'array', items: { type: 'string' } }\n }\n }\n data = {\n name: 'Bob',\n numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ],\n tags: ['Friend'],\n }\n \n treema = TreemaNode.make(null, {\n data: data\n schema: schema\n callbacks:\n change: ->\n fired.f += 1\n })\n treema.build()\n nameTreema = treema.childrenTreemas.name\n numbersTreema = treema.childrenTreemas.numbers\n tagsTreema = treema.childrenTreemas.tags\n fired.f = 0\n \n it 'fires when editing a field', ->\n valEl = nameTreema.getValEl()\n valEl.click()\n valEl.find('input').val('Boom').blur()\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you use set()', ->\n nameTreema.set('/', 'Foo')\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you use insert()', ->\n treema.insert('/numbers', {})\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you use delete()', ->\n treema.delete('/numbers/2') \n expect(fired.f).toBeGreaterThan(0)\n \n it 'does not fire when set() fails', ->\n nameTreema.set('/a/b/c/d/e', 'Foo')\n expect(fired.f).toBe(0)\n\n it 'does not fire when insert() fails', ->\n treema.insert('//a/b/c/d/e', {})\n expect(fired.f).toBe(0)\n\n it 'does not fire when delete() fails', ->\n treema.delete('//a/b/c/d/e')\n expect(fired.f).toBe(0)\n \n it 'fires when you add a new property to an object', ->\n treema.set('/blue', 'red')\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you add an object to an array', ->\n oldDataLength = numbersTreema.data.length\n numbersTreema.open()\n numbersTreema.$el.find('.treema-add-child').click()\n newDataLength = numbersTreema.data.length\n expect(oldDataLength).not.toBe(newDataLength)\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you add a non-collection to an array', ->\n tagsTreema.open()\n tagsTreema.$el.find('.treema-add-child').click()\n expect(fired.f).toBe(0)\n tabKeyPress(treema.$el.find('input').val('Star'))\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires when you delete an element in an array', ->\n tagsTreema.open()\n tagsTreema.$el.find('.treema-add-child').click()\n tabKeyPress(treema.$el.find('input').val('Star'))\n treema.endExistingEdits()\n tagTreema = tagsTreema.childrenTreemas[0]\n tagTreema.select()\n deleteKeyPress(treema.$el)\n expect(fired.f).toBeGreaterThan(0)\n\n it 'fires when you delete a property in an object', ->\n nameTreema.select()\n deleteKeyPress(treema.$el)\n expect(fired.f).toBeGreaterThan(0)\n \n it 'fires only once when you delete a selection of nodes', ->\n numbersTreema.open()\n numbersTreema.childrenTreemas[0].select()\n numbersTreema.childrenTreemas[1].shiftSelect()\n deleteKeyPress(treema.$el)\n expect(fired.f).toBe(1)\n ","describe 'canAddProperty', ->\n it 'works when properties is not defined, additionalProperties is false, and patternProperties is defined', ->\n schema = {\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-z]+$\": {}\n },\n \"additionalProperties\": false\n }\n data = {}\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n expect(treema.canAddProperty('test')).toBe(true)\n expect(treema.canAddProperty('1234')).toBe(false)\n","describe 'defaults', ->\n \n it 'shows properties for object nodes which are specified in a default object that are not included in the data', ->\n data = { }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n expect(treema.childrenTreemas.key).toBeDefined()\n\n it 'does not put default data into the containing data object', ->\n data = { }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n expect(treema.data.key).toBeUndefined()\n\n it 'puts data into the containing data object when its value is changed', ->\n data = { }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.set('key', 'testValue')\n expect(treema.data.key).toBe('testValue')\n expect(treema.childrenTreemas.key.integrated).toBe(true)\n expect(treema.$el.find('.treema-node').length).toBe(1)\n \n it 'keeps a default node around when you delete one with backup default data', ->\n data = { key: 'setValue' }\n schema = { default: { key: 'value' } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.delete('key')\n expect(treema.data.key).toBeUndefined()\n expect(treema.childrenTreemas.key).toBeDefined()\n expect(treema.childrenTreemas.key.integrated).toBe(false)\n expect(Object.keys(treema.data).length).toBe(0)\n\n it 'integrates up the chain when setting an inner default value', ->\n data = { }\n schema = { default: { innerObject: { key1: 'value1', key2: 'value2' } } }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n treema.childrenTreemas.innerObject.open()\n treema.childrenTreemas.innerObject.childrenTreemas.key1.set('', 'newValue')\n expect(JSON.stringify(treema.data)).toBe(JSON.stringify({innerObject: {key1: 'newValue'}}))\n \n it 'takes defaultData from the make options', ->\n data = { }\n schema = { }\n treema = TreemaNode.make(null, {data: data, schema: schema, defaultData: { key: 'value' }})\n treema.build()\n expect(treema.childrenTreemas.key).toBeDefined()\n\n it 'does not set defaults just by opening a collection', ->\n data = { }\n schema = { default: { inventory: { prop1: 'test', prop2: 'test' } } }\n treema = TreemaNode.make(null, {data: data, schema: schema, defaultData: { key: 'value' }})\n treema.build()\n treema.open(2)\n expect($.isEmptyObject(treema.data)).toBe(true)\n","describe 'Children Filter', ->\n\t \n data = [\n {\n \"id\": \"0001\",\n \"type\": \"Donut\",\n \"name\": \"Cake\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n { \"id\": \"1002\", \"name\": \"Chocolate\" },\n { \"id\": \"1003\", \"name\": \"Blueberry\" },\n { \"id\": \"1004\", \"name\": \"Devil's Food\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5005\", \"name\": \"Sugar\" },\n { \"id\": \"5007\", \"name\": \"Powdered Sugar\" },\n { \"id\": \"5006\", \"name\": \"Chocolate with Sprinkles\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0002\",\n \"type\": \"Donut\",\n \"name\": \"Raised\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5005\", \"name\": \"Sugar\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0001\",\n \"type\": \"Donut\",\n \"name\": \"Cake 2\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n { \"id\": \"1002\", \"name\": \"Chocolate\" },\n { \"id\": \"1003\", \"name\": \"Blueberry\" },\n { \"id\": \"1004\", \"name\": \"Devil's Food\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5005\", \"name\": \"Sugar\" },\n { \"id\": \"5007\", \"name\": \"Powdered Sugar\" },\n { \"id\": \"5006\", \"name\": \"Chocolate with Sprinkles\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0003\",\n \"type\": \"Donut\",\n \"name\": \"Old Fashioned\",\n \"ppu\": 0.55,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n { \"id\": \"1002\", \"name\": \"Chocolate\" }\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5002\", \"name\": \"Glazed\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n { \"id\": \"5004\", \"name\": \"Maple\" }\n ]\n },\n {\n \"id\": \"0004\",\n \"type\": \"Pastry\",\n \"name\": \"Croissant\",\n \"ppu\": 2.95,\n \"batters\":\n [\n { \"id\": \"1001\", \"name\": \"Regular\" },\n ]\n \"toppings\":\n [\n { \"id\": \"5001\", \"name\": \"None\" },\n { \"id\": \"5003\", \"name\": \"Chocolate\" },\n ]\n }\n ]\n\n schema = {\n type: 'array',\n items: {\n \"additionalProperties\": false,\n \"type\": \"object\",\n \"format\": \"product\",\n \"displayProperty\": 'name',\n \"properties\": {\n \"id\": { title: \"ID\", type: \"string\" },\n \"name\": { title: \"Name\", type: \"string\", maxLength: 20 },\n \"type\": { title: \"Product Type\", type: \"string\", enum: ['Donut', 'Pastry']},\n \"ppu\": { title: \"Price\", type: \"number\", format: \"price\"},\n \"batters\": {\n type: \"array\",\n title: \"Batter Options\",\n uniqueItems: true,\n maxItems: 4,\n items: {\n type: \"object\",\n format: \"batter\",\n properties: {\n \"id\": { type:\"string\" },\n \"type\": { type:\"string\" }\n }\n }\n },\n \"toppings\": {\n type: \"array\",\n title: \"Topping Options\",\n uniqueItems: true,\n maxItems: 7,\n items: {\n type: \"object\",\n format: \"topping\",\n properties: {\n \"id\": { type:\"string\" },\n \"type\": { type:\"string\" }\n }\n }\n }\n }\n }\n }\n\n treemaFilterHiddenClass = 'treema-filter-hidden'\n el = $('')\n treema = TreemaNode.make(el, {data: data, schema: schema})\n treema.build()\n\n createTitleFilter = (text)->\n \tfilter = (treemaNode, keyForParent)->\n \t return !text or text.trim() == '' or treemaNode.getValEl().text().toLowerCase().indexOf(text.toLowerCase()) >= 0\n return filter\n\n it 'Filter node on node title', ->\n\n treema.filterChildren(createTitleFilter(''))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(5)\n treema.clearFilter\n\n treema.filterChildren(createTitleFilter('cake'))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(2)\n treema.clearFilter\n\n treema.filterChildren(createTitleFilter('OLD fashioned'))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(1)\n treema.clearFilter\n\n treema.filterChildren(createTitleFilter('@@'))\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(0)\n treema.clearFilter\n\n it 'Nodes are always visible on null filter', ->\n treema.filterChildren(null)\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(5)\n treema.clearFilter\n\n treema.filterChildren(undefined)\n expect($(el).find('.treema-node').not('.' + treemaFilterHiddenClass).length).toBe(5)\n treema.clearFilter\n\n describe 'Navigate nodes using keyboard should skip hidden nodes', =>\n \n @firstTreema = $(el).find('.treema-node').eq(0).data('instance')\n @thirdTreema = $(el).find('.treema-node').eq(2).data('instance')\n\n @leftArrowPress = ($el) -> keyDown($el, 37)\n @upArrowPress = ($el) -> keyDown($el, 38)\n @rightArrowPress = ($el) -> keyDown($el, 39)\n @downArrowPress = ($el) -> keyDown($el, 40)\n\n \tit 'Select the first node.', =>\n @firstTreema.select()\n expect(@firstTreema.isSelected()).toBe(true)\n\n it 'Navigate to next node. The node is expected to be the third node, since the second node is hidden by filter', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.navigateSelection(1)\n expect(@thirdTreema.isSelected()).toBe(true)\n treema.clearFilter\n \n it 'Navigate back to previous node, the first node', =>\n treema.filterChildren(createTitleFilter('cake'))\n @thirdTreema.navigateSelection(-1)\n expect(@firstTreema.isSelected()).toBe(true)\n treema.clearFilter\n \n it 'Cyclic Navigation', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.navigateSelection(-1)\n @firstTreema.navigateSelection(-1)\n expect(@firstTreema.isSelected()).toBe(true)\n treema.clearFilter\n \n it 'When a node is open, the next node becomes its first child node', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.open()\n @firstTreema.navigateSelection(1)\n\n @firstChildren = @firstTreema.getNodeEl().find('.treema-children').children().eq(0).data('instance')\n @secondChildren = @firstTreema.getNodeEl().find('.treema-children').children().eq(1).data('instance')\n\n expect(@firstChildren.isSelected()).toBe(true)\n @firstChildren.navigateSelection(1)\n expect(@secondChildren.isSelected()).toBe(true)\n\n @firstTreema.close()\n treema.clearFilter\n \n it 'Simulate arrow key press', =>\n treema.filterChildren(createTitleFilter('cake'))\n @firstTreema.select()\n\n @downArrowPress(el) \n expect(@thirdTreema.isSelected()).toBe(true)\n\n @upArrowPress(el) \n expect(@firstTreema.isSelected()).toBe(true)\n\n treema.clearFilter","describe 'TreemaNode.delete', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'removes objects from an array', ->\n expect(treema.delete('/numbers/0')).toBeTruthy()\n numbers = treema.get('/numbers')\n expect(numbers.length).toBe(1)\n expect(numbers[0].type).toBe('Work')\n \n it 'removes properties from an object', ->\n expect(treema.delete('/numbers/0/type')).toBeTruthy()\n expect(treema.get('/numbers').type).toBeUndefined()\n expect(treema.get('/numbers/type')).toBeUndefined()\n","describe 'TreemaNode.get', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n \n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n\n it 'gets immediate values', ->\n expect(treema.get('/name')).toBe('Bob')\n \n it 'can search on object keys within an array', ->\n expect(treema.get('/numbers/type=Work').number).toBe('123-456-7890')\n \n it 'can start from a child', ->\n expect(nameTreema.get('/')).toBe('Bob')\n \n it 'returns undefined for invalid paths', ->\n expect(treema.get('waffles')).toBeUndefined()\n ","describe 'TreemaNode.insert', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'appends data to the end of an array', ->\n expect(treema.insert('/numbers', {'number':'4321'})).toBeTruthy()\n numbers = treema.get('/numbers')\n expect(numbers.length).toBe(3)\n expect(numbers[2].number).toBe('4321')\n\n it 'returns false for paths that are not arrays', ->\n expect(treema.insert('/numbers/0', 'boom')).toBeFalsy()\n \n it 'returns false for paths that do not exist', ->\n expect(treema.insert('/numbahs', 'boom')).toBeFalsy()","describe 'TreemaNode.set', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'object' } }\n }\n }\n data = { name: 'Bob', numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ]}\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'sets immediate values', ->\n expect(treema.set('/name', 'Bobby')).toBeTruthy()\n expect(treema.get('/name')).toBe('Bobby')\n \n it 'can search an object within an array', ->\n expect(treema.set('/numbers/type=Home/number', '1234')).toBeTruthy()\n expect(treema.get('/numbers/type=Home/number')).toBe('1234')\n \n it 'can set new properties', ->\n expect(treema.set('/numbers/0/daytime', true)).toBeTruthy()\n expect(treema.get('/numbers/0/daytime')).toBe(true)\n \n it 'updates the visuals of the node and all its parents', ->\n treema.childrenTreemas.numbers.open()\n treema.childrenTreemas.numbers.childrenTreemas[0].open()\n expect(treema.set('/numbers/0/type', 'Cell')).toBeTruthy()\n t = treema.childrenTreemas.numbers.$el.find('> .treema-row > .treema-value').text()\n expect(t.indexOf('Home')).toBe(-1)\n\n it 'affects the base data', ->\n expect(treema.data['numbers'][0]['daytime']).toBe(true)","describe 'Initialization', ->\n\n schema = { type: 'object', properties: { name: { type: 'string', 'default': 'Untitled'} } }\n data = { }\n el = $('')\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n\n it 'creates an $el if none is given', ->\n expect(treema.$el).toBeDefined()\n\n it 'uses the jQuery element given', ->\n elTreema = TreemaNode.make(el, {data: data, schema: schema})\n expect(elTreema.$el).toBe(el)\n\n# it 'grabs default data from an object schema', ->\n# noDataTreema = TreemaNode.make(null, {schema: schema})\n# expect(noDataTreema.data.name).toBe('Untitled')\n\n it 'opens up root collection nodes by default', ->\n treema.build()\n expect(treema.isOpen()).toBeTruthy()\n\ndescribe 'Schemaless', ->\n\n schema = type: 'object'\n data =\n errors: []\n warnings: [\n {\n hint: undefined\n userInfo: {}\n id: \"jshint_W099\"\n message: \"Mixed spaces and tabs.\"\n level: \"warning\"\n type: \"transpile\"\n ranges: [[[8, 0], [8, 3]]]\n }\n ]\n infos: []\n el = $('')\n treema = TreemaNode.make(el, {data: data, schema: schema})\n\n it 'initializes when given data for an empty schema', ->\n expect(treema.$el).toBeDefined()","do ->\n leftArrowPress = ($el) -> keyDown($el, 37)\n upArrowPress = ($el) -> keyDown($el, 38)\n rightArrowPress = ($el) -> keyDown($el, 39)\n downArrowPress = ($el) -> keyDown($el, 40)\n \n expectOneSelected = (t) ->\n selected = treema.getSelectedTreemas()\n expect(selected.length).toBe(1)\n expect(t).toBeDefined()\n expect(selected[0].$el[0]).toBe(t.$el[0]) if t and selected.length is 1 \n\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: ['string', 'array'] } }\n address: { type: 'string' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', ['123-456-7890']], 'address': 'Mars' }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n addressTreema = treema.childrenTreemas.address\n \n beforeEach ->\n treema.deselectAll()\n phoneTreema.close()\n \n describe 'Down arrow key press', ->\n it 'selects the top row if nothing is selected', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n downArrowPress(treema.$el)\n expect(nameTreema.isSelected()).toBeTruthy()\n \n it 'skips past closed collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n downArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n downArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n downArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n \n it 'traverses open collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n phoneTreema.open()\n downArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n downArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n downArrowPress(treema.$el)\n expectOneSelected(phoneTreema.childrenTreemas[0])\n# downArrowPress(treema.$el)\n# expectOneSelected(phoneTreema.childrenTreemas[1])\n# downArrowPress(treema.$el)\n# expectOneSelected(addressTreema)\n \n it 'does nothing if the last treema is selected', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n addressTreema.select()\n expectOneSelected(addressTreema)\n downArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n\n describe 'Up arrow key press', ->\n it 'selects the bottom row if nothing is selected', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n upArrowPress(treema.$el)\n expect(addressTreema.isSelected()).toBeTruthy()\n\n it 'skips past closed collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n upArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n upArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n\n it 'traverses open collections', ->\n expect(treema.getSelectedTreemas().length).toBe(0)\n phoneTreema.open()\n upArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema.childrenTreemas[1])\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema.childrenTreemas[0])\n upArrowPress(treema.$el)\n expectOneSelected(phoneTreema)\n upArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n\n it 'wraps around if the first treema is selected', ->\n nameTreema.select()\n expectOneSelected(nameTreema)\n upArrowPress(treema.$el)\n expectOneSelected(addressTreema)\n\n describe 'Right arrow key press', ->\n it 'does nothing if the selected row isn\\'t a collection', ->\n nameTreema.select()\n expectOneSelected(nameTreema)\n rightArrowPress(treema.$el)\n expectOneSelected(nameTreema)\n \n it 'opens a collection if a collection is selected', ->\n expect(phoneTreema.isClosed()).toBeTruthy()\n phoneTreema.select()\n rightArrowPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema)\n \n describe 'Left arrow key press', ->\n it 'closes an open, selected collection', ->\n phoneTreema.open()\n phoneTreema.select()\n leftArrowPress(treema.$el)\n expect(phoneTreema.isClosed()).toBeTruthy()\n expectOneSelected(phoneTreema)\n \n it 'closes the selection if it can be closed, otherwise moves the selection up a level', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].select()\n leftArrowPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema)\n leftArrowPress(treema.$el)\n expect(phoneTreema.isClosed()).toBeTruthy()\n expectOneSelected(phoneTreema)\n \n it 'affects one collection at a time, deepest first', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].open()\n phoneTreema.childrenTreemas[1].childrenTreemas[0].select()\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.childrenTreemas[1].isOpen()).toBeTruthy()\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema.childrenTreemas[1])\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.childrenTreemas[1].isClosed()).toBeTruthy()\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema.childrenTreemas[1])\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n expectOneSelected(phoneTreema)\n\n leftArrowPress(treema.$el)\n expect(phoneTreema.isClosed()).toBeTruthy()\n expectOneSelected(phoneTreema)","describe 'Delete key press', ->\n deleteKeyPress = ($el) -> keyDown($el, 8)\n\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: ['string', 'array'] } }\n address: { type: 'string' }\n }\n }\n original_data = { name: 'Bob', numbers: ['401-401-1337', ['123-456-7890']], 'address': 'Mars' }\n treema = nameTreema = addressTreema = phoneTreema = null\n \n rebuild = ->\n copy = $.extend(true, {}, original_data)\n treema = TreemaNode.make(null, {data: copy, schema: schema})\n treema.build()\n \n nameTreema = treema.childrenTreemas.name\n addressTreema = treema.childrenTreemas.address\n phoneTreema = treema.childrenTreemas.numbers\n\n expectOneSelected = (t) ->\n selected = treema.getSelectedTreemas()\n expect(selected.length).toBe(1)\n expect(selected[0]).toBe(t)\n\n beforeEach ->\n rebuild()\n \n it 'does nothing when nothing is selected', ->\n deleteKeyPress(treema.$el)\n expect(treema.data.name).toBe(original_data.name)\n expect(treema.data.address).toBe(original_data.address)\n \n it 'removes a selected row', ->\n nameTreema.select()\n deleteKeyPress(treema.$el)\n expect(treema.data.name).toBeUndefined()\n expect(treema.childrenTreemas.name).toBeUndefined()\n expect(treema.childrenTreemas.address).toBeTruthy()\n \n it 'removes all selected rows', ->\n nameTreema.select()\n addressTreema.toggleSelect()\n deleteKeyPress(treema.$el)\n expect(treema.data.name).toBeUndefined()\n expect(treema.data.address).toBeUndefined()\n expect(treema.childrenTreemas.name).toBeUndefined()\n expect(treema.childrenTreemas.address).toBeUndefined()\n\n xit 'removes single elements of a collection one at a time, then the collection itself', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].open()\n phoneTreema.childrenTreemas[0].select()\n expect(treema.data.numbers.length).toBe(2)\n\n # deletes '401...', selects ['123...'] (which is now at index 0)\n # stays at the same level, does not enter the open collection\n deleteKeyPress(treema.$el)\n expect(treema.data.numbers.length).toBe(1)\n expectOneSelected(phoneTreema.childrenTreemas[0])\n\n # deletes ['123...'], selects numbers\n # when there are no more elements, goes to the parent\n deleteKeyPress(treema.$el)\n expect(treema.data.numbers.length).toBe(0)\n expectOneSelected(phoneTreema)\n\n # deletes numbers, selects address\n # when there's an element the one just deleted, it goes down\n deleteKeyPress(treema.$el) \n expect(treema.data.numbers).toBeUndefined()\n expectOneSelected(addressTreema)\n\n # deletes address, selects name\n # when there's no element after the one just deleted, it goes up\n deleteKeyPress(treema.$el) \n expect(treema.data.address).toBeUndefined()\n expectOneSelected(nameTreema)\n\n # deletes name, nothing more to select\n # when there are no more elements, select nothing\n deleteKeyPress(treema.$el) \n expect(treema.data.name).toBeUndefined()\n expect(treema.getSelectedTreemas().length).toBe(0)\n expect(Object.keys(treema.data).length).toBe(0)\n \n it 'removes a row if it\\'s being edited and there\\'s nothing in the focused input', ->\n nameTreema.edit()\n nameTreema.$el.find('input').val('')\n deleteKeyPress(nameTreema.$el.find('input'))\n expect(treema.data.name).toBeUndefined()\n expectOneSelected(phoneTreema)\n\n it 'performs normally if a focused input has value', ->\n nameTreema.edit()\n deleteKeyPress(nameTreema.$el.find('input'))\n expect(treema.data.name).toBeTruthy()\n","describe 'Enter key press', ->\n enterKeyPress = ($el) -> keyDown($el, 13)\n\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'string', minLength: 4 } }\n address: { type: 'string' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890'], 'address': 'Mars' }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n \n afterEach ->\n treema.endExistingEdits()\n phoneTreema.close()\n \n it 'edits the last selected row', ->\n nameTreema.select()\n enterKeyPress(treema.$el)\n expect(nameTreema.isEditing()).toBeTruthy()\n \n it 'saves the current row and goes on to the next value in the collection if there is one', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('4321')\n enterKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[0].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('4321')\n \n it 'traverses into and out of open collections', ->\n phoneTreema.open()\n nameTreema.edit()\n enterKeyPress(nameTreema.$el)\n expect(phoneTreema.isSelected()).toBeTruthy()\n enterKeyPress(treema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n enterKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n \n it 'opens closed collections', ->\n phoneTreema.select()\n enterKeyPress(treema.$el)\n expect(phoneTreema.isOpen()).toBeTruthy()\n \n it 'shows errors and moves on when saving an invalid row', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('1')\n enterKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[0].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('1')\n expect(treema.isValid()).toBeFalsy()\n\n it 'goes backwards if shift is pressed', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].edit()\n\n event = jQuery.Event(\"keydown\")\n event.which = 13\n event.shiftKey = true\n phoneTreema.childrenTreemas[1].$el.trigger(event)\n\n expect(phoneTreema.childrenTreemas[1].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n \n it 'edits the first child in a collection if a collection is selected', ->\n phoneTreema.open()\n phoneTreema.select()\n enterKeyPress(phoneTreema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n","describe '\"N\" key press', ->\n nKeyPress = ($el) -> keyDown($el, 78)\n enterKeyPress = ($el) -> keyDown($el, 13)\n\n schema = {\n type: 'array',\n maxItems: 3,\n items: { type: 'string' }\n }\n data = ['401-401-1337', '123-456-7890']\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'creates a new row for the currently selected collection', ->\n treema.childrenTreemas[0].select()\n expect(treema.childrenTreemas[2]).toBeUndefined()\n nKeyPress(treema.childrenTreemas[0].$el)\n expect(treema.childrenTreemas[2]).toBeUndefined()\n enterKeyPress(treema.$el.find('input').val('410-555-1023'))\n expect(treema.childrenTreemas[2]).not.toBeUndefined()\n treema.childrenTreemas[2].display()\n treema.childrenTreemas[2].select()\n expect(treema.childrenTreemas[2]).not.toBeUndefined()\n \n it 'does not create a new row when there\\'s no more space', ->\n expect(treema.data.length).toBe(3)\n nKeyPress(treema.childrenTreemas[0].$el)\n expect(treema.data.length).toBe(3)","# almost exactly the same as enter, except it keeps focus on a row that is invalid\n\ndescribe 'Tab key press', ->\n tabKeyPress = ($el) -> keyDown($el, 9)\n \n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'string', minLength: 4 } }\n address: { type: 'string' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890'], 'address': 'Mars' }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n addressTreema = treema.childrenTreemas.address\n \n afterEach ->\n treema.endExistingEdits()\n phoneTreema.close()\n \n it 'edits the last selected row', ->\n nameTreema.select()\n tabKeyPress(treema.$el)\n expect(nameTreema.isEditing()).toBeTruthy()\n\n it 'saves the current row and goes on to the next value in the collection if there is one', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('4321')\n tabKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[0].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('4321')\n\n it 'traverses into and out of open collections', ->\n phoneTreema.open()\n nameTreema.edit()\n tabKeyPress(nameTreema.$el)\n expect(phoneTreema.isSelected()).toBeTruthy()\n tabKeyPress(treema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n tabKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[1].isEditing()).toBeTruthy()\n\n it 'skips over closed collections', ->\n nameTreema.edit()\n tabKeyPress(nameTreema.$el)\n expect(phoneTreema.isSelected()).toBeTruthy()\n tabKeyPress(treema.$el)\n expect(addressTreema.isEditing()).toBeTruthy()\n\n it 'shows errors and stays put when saving an invalid row', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[0].edit()\n phoneTreema.childrenTreemas[0].$el.find('input').val('1')\n tabKeyPress(phoneTreema.childrenTreemas[0].$el)\n expect(phoneTreema.childrenTreemas[1].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n expect(treema.data.numbers[0]).toBe('1')\n expect(treema.isValid()).toBeFalsy()\n\n it 'goes backwards if shift is pressed', ->\n phoneTreema.open()\n phoneTreema.childrenTreemas[1].edit()\n\n event = jQuery.Event(\"keydown\")\n event.which = 9\n event.shiftKey = true\n phoneTreema.childrenTreemas[1].$el.trigger(event)\n\n expect(phoneTreema.childrenTreemas[1].isDisplaying()).toBeTruthy()\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n\n it 'edits the first child in a collection if a collection is selected', ->\n phoneTreema.open()\n phoneTreema.select()\n tabKeyPress(phoneTreema.$el)\n expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy()\n \n xit 'goes around in a loop', ->\n # this test doesn't work because focus on the add button doesn't work in a testing condition...\n $('body').append(treema.$el)\n addressTreema.select()\n tabKeyPress(treema.$el) # editing address\n tabKeyPress($(document.activeElement)) # selecting add button\n expect(nameTreema.isEditing()).toBeTruthy()\n treema.$el.remove()\n \n","describe 'Mouse click behavior', ->\n\n treema = nameTreema = phoneTreema = null\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: 'string' } }\n }\n }\n \n beforeEach ->\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890'] }\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n phoneTreema = treema.childrenTreemas.numbers\n \n shiftClick = ($el) ->\n event = jQuery.Event(\"click\")\n event.shiftKey = true\n $el.trigger(event)\n \n metaClick = ($el) ->\n event = jQuery.Event(\"click\")\n event.metaKey = true\n $el.trigger(event)\n \n it 'starts editing if you click the value', ->\n expect(nameTreema.isDisplaying()).toBe(true)\n nameTreema.$el.find('.treema-value').click()\n expect(nameTreema.isEditing()).toBe(true)\n \n it 'opens a collection if you click the value', ->\n expect(phoneTreema.isClosed()).toBe(true)\n phoneTreema.$el.find('.treema-value').click()\n expect(phoneTreema.isOpen()).toBe(true)\n \n it 'selects and unselects the row if you click something other than the value', ->\n expect(nameTreema.isSelected()).toBe(false)\n nameTreema.$el.click()\n expect(nameTreema.isSelected()).toBe(true)\n nameTreema.$el.click()\n expect(nameTreema.isSelected()).toBe(false)\n\n it 'selects along all open rows if you shift click', ->\n phoneTreema.open()\n nameTreema.$el.click()\n shiftClick(phoneTreema.childrenTreemas[0].$el)\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(true)\n expect(phoneTreema.childrenTreemas[0].isSelected()).toBe(true)\n expect(phoneTreema.childrenTreemas[1].isSelected()).toBe(false)\n \n it 'keeps the clicked row selected if there are multiple selections to begin with', ->\n nameTreema.$el.click()\n shiftClick(phoneTreema.$el)\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(true)\n nameTreema.$el.click()\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(false)\n \n it 'toggles the select state if you ctrl/meta click', ->\n nameTreema.$el.click()\n metaClick(phoneTreema.$el)\n expect(nameTreema.isSelected()).toBe(true)\n expect(phoneTreema.isSelected()).toBe(true)\n metaClick(nameTreema.$el)\n expect(nameTreema.isSelected()).toBe(false)\n expect(phoneTreema.isSelected()).toBe(true)\n","describe 'readOnly in schema', ->\n\n schema = {\n type: 'object',\n properties: {\n name: { \n type: 'string',\n readOnly: true\n },\n\n numbers: { \n type: 'array', \n items: { type: 'object' }, \n readOnly: true \n },\n \n tags: {\n type: 'array',\n items: { type: 'string', readOnly: true } \n },\n \n tags2: {\n type: 'array',\n items: { type: 'string' },\n readOnly: true\n }\n\n map: {\n type: 'object',\n readOnly: true\n }\n }\n }\n data = {\n name: 'Bob',\n numbers: [\n {'number':'401-401-1337', 'type':'Home'},\n {'number':'123-456-7890', 'type':'Work'}\n ],\n tags: ['Friend'],\n tags2: ['Friend'],\n map: {\n 'string': 'String',\n 'object': { 'key': 'value' }\n }\n }\n \n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'prevents editing of readOnly non-collection properties', ->\n expect(treema.childrenTreemas.name.canEdit()).toBe(false)\n \n # arrays\n \n it 'prevents removing from readOnly arrays', ->\n treema.childrenTreemas.numbers.remove()\n expect(treema.data.numbers).not.toBeUndefined()\n \n it 'prevents adding items to readOnly arrays', ->\n expect(treema.childrenTreemas.numbers.canAddChild()).toBe(false)\n \n it 'prevents removing readOnly items from arrays which are not readOnly', ->\n treema.childrenTreemas.tags.open()\n treema.childrenTreemas.tags.childrenTreemas[0].remove()\n expect(treema.data.tags.length).toBe(1)\n \n it 'prevents editing non-collection items in readOnly arrays', ->\n treema.childrenTreemas.tags2.open()\n expect(treema.childrenTreemas.tags2.childrenTreemas[0].canEdit()).toBe(false)\n \n # objects\n\n it 'prevents removing from readOnly objects', ->\n treema.childrenTreemas.map.remove()\n expect(treema.data.map).not.toBeUndefined()\n\n it 'prevents adding to readOnly objects', ->\n expect(treema.childrenTreemas.map.canAddChild()).toBe(false)\n\n it 'prevents removing readOnly properties from objects which are not readOnly', ->\n treema.childrenTreemas.name.remove()\n treema.childrenTreemas.tags.childrenTreemas[0].remove()\n expect(treema.data.tags.length).toBe(1)\n\n it 'prevents editing non-collection properties in readOnly objects', ->\n treema.childrenTreemas.map.open()\n expect(treema.childrenTreemas.map.childrenTreemas.string.canEdit()).toBe(false)\n \n","describe 'schema property \"required\"', ->\n treema = null\n beforeEach ->\n schema = {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"integer\": { type: \"integer\" },\n \"string\": { type: \"string\" },\n \"number\": { type: \"number\" },\n \"null\": { type: \"null\" },\n \"boolean\": { type: \"boolean\" },\n \"array\": { type: \"array\", items: { type: 'number', default: 42 } },\n \"object\": { type: \"object\" },\n \"def\": { 'default': 1337 }\n },\n \"required\": ['integer', 'string', 'number', 'null','boolean','array','object','def']\n }\n data = {}\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n it 'populates all required values with generic data', ->\n expect(treema.get('/integer')).toBe(0)\n expect(treema.get('/string')).toBe('')\n expect(treema.get('/number')).toBe(0)\n expect(treema.get('/null')).toBe(null)\n expect(treema.get('/boolean')).toBe(false)\n expect(JSON.stringify(treema.get('/array'))).toBe(JSON.stringify([]))\n expect(JSON.stringify(treema.get('/object'))).toBe(JSON.stringify({}))\n\n it 'populates required values with defaults', ->\n expect(treema.get('/def')).toBe(1337)\n treema.childrenTreemas['array'].addNewChild()\n expect(treema.$el.find('input').val()).toBe('42')\n \ndescribe 'schema property \"required\"', ->\n it 'populates data from the object\\'s default property', ->\n schema =\n type: 'object'\n default: { key1: 'object default' }\n required: ['key1']\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key1).toBe('object default')\n\n it 'populates data based on the child schema type', ->\n schema =\n type: 'object'\n required: ['key2']\n properties:\n key2: { type: 'number' }\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key2).toBe(0)\n\n it 'populates data from the child schema\\'s default property', ->\n schema =\n type: 'object'\n required: ['key3']\n properties:\n key3: { default: 'inner default' }\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key3).toBe('inner default')\n\n it 'populates data as an empty string if nothing else is available', ->\n schema =\n required: ['key4']\n treema = $('').treema({ schema:schema, data:{} })\n treema.build()\n expect(treema.data.key4).toBe('')\n","do ->\n expectOpen = (t) ->\n expect(t).toBeDefined()\n expect(t.isClosed()).toBeFalsy()\n\n expectClosed = (t) ->\n expect(t).toBeDefined()\n expect(t.isClosed()).toBeTruthy()\n\n schema =\n type: 'object',\n properties:\n name:\n type: 'string'\n info:\n type: 'object'\n properties:\n numbers:\n type: 'array',\n items:\n type: ['string', 'array']\n data = name: 'Thor', info: {numbers: ['401-401-1337', ['123-456-7890']]}\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n\n beforeEach ->\n treema.deselectAll()\n treema.close()\n\n describe 'open', ->\n it 'can open n levels deep', ->\n expectClosed(treema)\n treema.open(2)\n expectOpen(treema)\n infoTreema = treema.childrenTreemas.info\n expectOpen(infoTreema)\n phoneTreema = infoTreema.childrenTreemas.numbers\n expectClosed(phoneTreema)\n","describe 'Undo-redo behavior', ->\n schema = {\n type: 'object',\n properties: {\n name: { type: 'string' }\n numbers: { type: 'array', items: { type: ['string', 'array'] } }\n address: { type: 'string' }\n completed: { type: 'boolean' }\n }\n }\n data = { name: 'Bob', numbers: ['401-401-1337', '123-456-7890', '456-7890-123'], address: 'Mars', completed: false }\n originalData = jQuery.extend(true, {}, data)\n\n treema = TreemaNode.make(null, {data: data, schema: schema})\n treema.build()\n nameTreema = treema.childrenTreemas.name\n numbersTreema = treema.childrenTreemas.numbers\n addressTreema = treema.childrenTreemas.address\n completedTreema = treema.childrenTreemas.completed\n\n it 'does nothing when there are no actions to be undone', ->\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.data).toEqual(originalData)\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n # Edit actions---------------------------------------------------------------------\n it 'reverts a set object property', ->\n path = '/name'\n treema.set '/name', 'Alice'\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get(path)).toEqual('Alice')\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n it 'reverts a set array element', ->\n path = '/numbers/1'\n treema.set path, '1'\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get(path)).toEqual('1')\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n it 'reverts a toggled boolean value', ->\n completedTreema.toggleValue()\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get('/completed')).toBe(true)\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n # Insert actions---------------------------------------------------------------------\n it 'reverts an element inserted into an array', ->\n path = '/numbers'\n treema.insert path, '1' \n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n numbersData = treema.get path\n expect(numbersData[numbersData.length-1]).toEqual('1')\n treema.set '/', jQuery.extend(true, {}, originalData)\n \n # Delete actions----------------------------------------------------------------------\n it 'reverts a deleted object property', ->\n path = '/name'\n treema.delete path\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.get(path)).toBe(undefined)\n treema.set '/', jQuery.extend(true, {}, originalData)\n\n it 'reverts a element deleted from the middle of an array', ->\n path = '/numbers/1'\n treema.delete path\n treema.undo()\n expect(treema.data).toEqual(originalData)\n treema.redo()\n expect(treema.data).toNotEqual(originalData)\n treema.set '/', jQuery.extend(true, {}, originalData) \n\n #Combinations of actions\n it 'reverts a series of edit, insert and delete actions', ->\n treema.set '/name', 'Alice'\n treema.insert '/numbers', '1'\n treema.delete '/numbers'\n\n treema.undo()\n expect(treema.get('/numbers')).toBeDefined()\n treema.undo()\n expect(treema.get('/numbers')).toEqual(numbersTreema.data)\n treema.undo()\n expect(treema.data).toEqual(originalData)\n\n treema.redo()\n expect(treema.get('/name')).toBe('Alice')\n treema.redo()\n numbersData = treema.get '/numbers'\n expect(numbersData[numbersData.length-1]).toEqual('1')\n treema.redo()\n expect(treema.get('/numbers')).toBeUndefined()\n","describe 'utilities', ->\n backupJQuery = $\n \n beforeEach ->\n window.jQuery = undefined\n window.$ = undefined\n \n afterEach ->\n window.jQuery = backupJQuery\n window.$ = backupJQuery\n \n describe 'tests', ->\n it 'run in an environment without jQuery', ->\n hadError = false\n try\n $('body')\n catch\n hadError = true\n expect(hadError).toBe(true)\n \n describe 'populateDefaults', ->\n it 'walks through data and applies schema defaults to data', ->\n schema = {\n type: 'object'\n default: { innerObject: {}, someProp: 1 }\n properties:\n innerObject: { default: { key1: 'value1', key2: 'value2' }}\n }\n \n data = null\n \n result = TreemaNode.utils.populateDefaults(data, schema)\n \n expect(result).toBeDefined()\n expect(result.innerObject).toBeDefined()\n expect(result.innerObject.key1).toBe('value1')\n expect(result.innerObject.key2).toBe('value2')\n \n it 'merges in default objects that are adjacent to extant data', ->\n schema = {\n type: 'object'\n properties:\n innerObject: { default: { key1: 'value1', key2: 'value2' }}\n }\n\n data = { innerObject: { key1: 'extantData' }}\n\n result = TreemaNode.utils.populateDefaults(data, schema)\n\n expect(result).toBeDefined()\n expect(result.innerObject).toBeDefined()\n expect(result.innerObject.key1).toBe('extantData')\n expect(result.innerObject.key2).toBe('value2')\n\n \n # In order to support the default structure below, would need to\n # make populateData a bit more complicated, with some custom merging logic.\n # Going to see if we can get away without it first.\n \n# it 'merges default objects from parent schemas down to child extant data', ->\n# schema = {\n# type: 'object'\n# default: { innerObject: { key1: 'value1', key2: 'value2' } }\n# }\n#\n# data = { innerObject: { prop1: 'extantData' } }\n#\n# result = TreemaNode.utils.populateDefaults(data, schema)\n#\n# expect(result.innerObject).toBeDefined()\n# expect(result.innerObject.prop1).toBe('extantData')\n# expect(result.innerObject.prop2).toBe('2')\n \n describe 'walk', ->\n it 'calls a callback on every piece of data in a JSON object, providing path, data and working schema', ->\n schema = {\n type: 'object'\n properties:\n key1: { title: 'Number 1' }\n key2: { title: 'Number 2' }\n }\n \n data = { key1: 1, key2: 2 }\n \n paths = []\n values = []\n \n TreemaNode.utils.walk data, schema, null, (path, data, schema) ->\n paths.push(path)\n values.push(data)\n \n expect(paths.length).toBe(3)\n \n expect('' in paths).toBe(true)\n expect('key1' in paths).toBe(true)\n expect('key2' in paths).toBe(true)\n \n expect(data in values).toBe(true)\n expect(data.key1 in values).toBe(true)\n expect(data.key2 in values).toBe(true)\n \n it 'traverses arrays', ->\n schema = {\n type: 'array'\n items: {\n type: 'object'\n marker: true\n }\n }\n \n data = [{}]\n foundIt = false\n \n TreemaNode.utils.walk data, schema, null, (path, data, schema) ->\n if path is '0'\n expect(schema.marker).toBe(true)\n foundIt = true\n \n expect(foundIt).toBe(true)\n \n describe 'getChildSchema', ->\n it 'returns child schemas from properties', ->\n schema = { properties: { key1: { title: 'some title' } }}\n childSchema = TreemaNode.utils.getChildSchema('key1', schema)\n expect(childSchema.title).toBe('some title')\n \n it 'returns child schemas from additionalProperties', ->\n schema = { additionalProperties: { title: 'some title' } }\n childSchema = TreemaNode.utils.getChildSchema('key1', schema)\n expect(childSchema.title).toBe('some title')\n \n it 'returns child schemas from patternProperties', ->\n schema = { patternProperties: { '^[a-z]+$': { title: 'some title' } }}\n childSchema = TreemaNode.utils.getChildSchema('key', schema)\n expect(childSchema.title).toBe('some title')\n childSchema = TreemaNode.utils.getChildSchema('123', schema)\n expect(childSchema.title).toBeUndefined()\n\n it 'returns child schemas from an items schema', ->\n schema = { items: { title: 'some title' } }\n childSchema = TreemaNode.utils.getChildSchema(0, schema)\n expect(childSchema.title).toBe('some title')\n\n it 'returns child schemas from an items array of schemas', ->\n schema = { items: [{ title: 'some title' }] }\n childSchema = TreemaNode.utils.getChildSchema(0, schema)\n expect(childSchema.title).toBe('some title')\n childSchema = TreemaNode.utils.getChildSchema(1, schema)\n expect(childSchema.title).toBeUndefined()\n \n it 'returns child schemas from additionalItems', ->\n schema = { items: [{ title: 'some title' }], additionalItems: { title: 'another title'} }\n childSchema = TreemaNode.utils.getChildSchema(1, schema)\n expect(childSchema.title).toBe('another title')\n\n describe 'buildWorkingSchemas', ->\n it 'returns the same single schema if there are no combinatorials or references', ->\n schema = {}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas[0] is schema).toBeTruthy()\n \n it 'combines allOf into a single schema', ->\n schema = { title: 'title', allOf: [ { description: 'description' }, { type: 'number' } ]}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas.length).toBe(1)\n workingSchema = workingSchemas[0]\n expect(workingSchema.title).toBe('title')\n expect(workingSchema.description).toBe('description')\n expect(workingSchema.type).toBe('number')\n \n it 'creates a separate working schema for each anyOf', ->\n schema = { title: 'title', anyOf: [{ type: 'string' }, { type: 'number' }]}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas.length).toBe(2)\n types = (schema.type for schema in workingSchemas)\n expect('string' in types).toBe(true)\n expect('number' in types).toBe(true)\n\n it 'creates a separate working schema for each oneOf', ->\n schema = { title: 'title', oneOf: [{ type: 'string' }, { type: 'number' }]}\n workingSchemas = TreemaNode.utils.buildWorkingSchemas(schema)\n expect(workingSchemas.length).toBe(2)\n types = (schema.type for schema in workingSchemas)\n expect('string' in types).toBe(true)\n expect('number' in types).toBe(true)\n \n # Eventually might want more advanced behaviors, like smartly combining types from \"allOf\" or \"oneOf\" schemas.\n # But for now this more naive combination behavior will do.\n","describe 'showing errors', ->\n it 'does not go away when you close and open a collection', ->\n schema = {\n type: 'object',\n additionalProperties: false\n }\n data = { someProp: ['test', 1, 2, 3] }\n\n treema = $('').treema({ schema:schema, data:data })\n treema.build()\n expect(treema.$el.find('.treema-error').length).toBe(1)\n window.treema = treema\n treema.childrenTreemas.someProp.open()\n expect(treema.$el.find('.treema-error').length).toBe(1)\n treema.childrenTreemas.someProp.close()\n expect(treema.$el.find('.treema-error').length).toBe(1)\n"]} \ No newline at end of file diff --git a/dev/server.js b/dev/server.js index f016ce2..32fa96a 100644 --- a/dev/server.js +++ b/dev/server.js @@ -7,10 +7,10 @@ /* Source: http://stackoverflow.com/questions/10434001/static-files-with-express-js */ -module.exports.startServer = startServer = function() { +module.exports.startServer = startServer = function(port, path, callback) { var express = require('express'); var app = express(); - var path = require('path'); + var Path = require('path'); app.get('/db/fastfood', function(req, res) { // for testing the database search feature @@ -34,11 +34,11 @@ module.exports.startServer = startServer = function() { }); - app.use(express.static(__dirname)); // Current directory is root + app.use(express.static(Path.join(__dirname, path))); // Current directory is root //app.use(express.static(path.join(__dirname, 'test'))); // "public" off of current is root - app.listen(9090); - console.log('Listening on port 9090'); + app.listen(port, callback); + console.log("Listening on port " + port); return app; }; @@ -70,4 +70,4 @@ restaurants = [ "The Hat", "The Whole Donut", "Togo's", "Tudor's Biscuit World", "The Varsity", "Wendy's", "Wetzel's Pretzels", "Whataburger", "White Castle", "Wienerschnitzel", "Winchell's Donuts", "Wingstop", "WingStreet", "Winstead's", "Wing Zone", "Woody's Chicago Style", "Yum-Yum Donuts", "Zaxby's" -] \ No newline at end of file +] diff --git a/package.json b/package.json index b7bc961..2087304 100644 --- a/package.json +++ b/package.json @@ -32,14 +32,11 @@ "express": "3.0.6" }, "devDependencies": { - "jade": "0.33.x", - "javascript-brunch": "> 1.0 < 1.8", "coffee-script-brunch": "> 1.0 < 1.8", "coffeelint-brunch": "> 1.0 < 1.8", "sass-brunch": "> 1.0 < 1.8", "css-brunch": "> 1.0 < 1.8", - "jade-brunch": "> 1.0 < 1.8", "uglify-js-brunch": "> 1.0 < 1.8", "clean-css-brunch": "> 1.0 < 1.8", "auto-reload-brunch": "> 1.0 < 1.8", @@ -47,7 +44,7 @@ "jasmine-node": "1.2.x" }, - "license": "Copyright © 2013 Scott Erickson", + "license": "MIT", "private": false, "engines": { "node": "0.8.x" diff --git a/src/base.coffee b/src/base.coffee index d28e474..f92d093 100644 --- a/src/base.coffee +++ b/src/base.coffee @@ -59,7 +59,7 @@ class TreemaNode if e.dataPath is my_path e.subDataPath = '' else - e.subDataPath = e.dataPath[..my_path.length] + e.subDataPath = e.dataPath[..my_path.length] if @workingSchema moreErrors = @tv4.validateMultiple(@data, @workingSchema).errors @@ -77,7 +77,7 @@ class TreemaNode @tv4 = root.tv4 # Abstract functions -------------------------------------------------------- - saveChanges: (oldData)-> + saveChanges: (oldData) -> return if oldData is @data @addTrackedAction {'oldData':oldData, 'newData':@data, 'path':@getPath(), 'action':'edit'} getChildSchema: (key) -> TreemaNode.utils.getChildSchema(key, @workingSchema) @@ -180,7 +180,7 @@ class TreemaNode for key in ['data', 'defaultData', 'schema', 'type'] @[key] = @settings[key] if @settings[key]? delete @settings[key] - + build: -> @$el.addClass('treema-node').addClass('treema-clearfix') @$el.empty().append($(@nodeTemplate)) @@ -242,7 +242,7 @@ class TreemaNode select.append(option) select.change(@onSelectType) @$el.find('> .treema-row').prepend(select) - + getTypeName: (type) -> { null: 'null', @@ -274,6 +274,9 @@ class TreemaNode @manageCopyAndPaste e if e.ctrlKey or e.metaKey @$el.keyup (e) => + if e.which in [17, 91] # ctrl, meta + @targetOfCopyPaste?.removeClass('treema-target-of-copy-paste') + @targetOfCopyPaste = null delete @keysPreviouslyDown[e.which] manageCopyAndPaste: (e) -> @@ -293,11 +296,20 @@ class TreemaNode try newData = JSON.parse newData catch e + @$el.trigger { + type: 'treema-error' + message: 'Could not parse pasted data as JSON.' + } return result = target.tv4.validateMultiple(newData, target.schema) if result.valid target.set('/', newData) + @$el.trigger 'treema-paste' else + @$el.trigger { + type: 'treema-error' + message: 'Data provided is invalid according to schema.' + } console.log "not pasting", newData, "because it's not valid:", result ), 5 else @@ -309,12 +321,20 @@ class TreemaNode @saveScrolls() @$clipboardContainer.find('.treema-clipboard').focus().select() @loadScrolls() - else unless window.getSelection()?.toString() or document.selection?.createRange().text + else # Get ready for a possible Ctrl+C copy @saveScrolls() - @$clipboardContainer ?= $('').appendTo(@$el) + if not @$clipboardContainer + @$clipboardContainer = $('').appendTo(@$el) + @$clipboardContainer.on 'paste', => + @targetOfCopyPaste?.removeClass('treema-target-of-copy-paste') + @$clipboardContainer.on 'copy', => + @$el.trigger 'treema-copy' + @targetOfCopyPaste?.removeClass('treema-target-of-copy-paste') + @targetOfCopyPaste = target.$el + @targetOfCopyPaste.addClass('treema-target-of-copy-paste') @$clipboardContainer.empty().show() - @$clipboard = $('').val(JSON.stringify(target.data)).appendTo(@$clipboardContainer).focus().select() + @$clipboard = $('').val(JSON.stringify(target.getData(), null, ' ')).appendTo(@$clipboardContainer).focus().select() @loadScrolls() broadcastChanges: (e) -> @@ -464,7 +484,7 @@ class TreemaNode @getRoot().redo() else @getRoot().undo() - + # Tree traversing/navigation ------------------------------------------------ # (traversing means editing and adding fields, pressing enter and tab) # (navigation means selecting fields, pressing arrow keys) @@ -491,9 +511,8 @@ class TreemaNode return unless ctx?.origin selected = $(ctx.origin).data('instance') # Super defensive, this happens when an outside force removes this treema in a callback - # Need to have Treema send out events only after everything else is done. - return unless selected - if offset > 0 and aggressive and selected.collection and selected.isClosed() + # Need to have Treema send out events only after everything else is done. + if offset > 0 and aggressive and selected and selected.collection and selected.isClosed() return selected.open() targetEl = if offset > 0 then ctx.next else ctx.prev @@ -639,7 +658,7 @@ class TreemaNode parentPaths.push treema.parent?.getPath() @addTrackedAction { 'data':data, 'path':paths, 'parentPath':parentPaths, 'action':'delete' } for treema in selected - treema.remove() + treema.remove() toSelect.select() if toSelect and not @getSelectedTreemas().length @getRoot().hush = false @broadcastChanges() @@ -656,7 +675,7 @@ class TreemaNode tempError = @createTemporaryError('read only') @$el.prepend(tempError) return false - + if @defaultData isnt undefined options = $.extend({}, @settings, { defaultData: @defaultData, schema: @workingSchema }, ) newNode = TreemaNode.make(null, options, @parent, @keyForParent) @@ -677,7 +696,7 @@ class TreemaNode @$el.removeClass('treema-default-stub') @$el.addClass('treema-default-stub') if @isDefaultStub() and not @parent.isDefaultStub() child.updateDefaultClass() for key, child of @childrenTreemas - + # Opening/closing collections ----------------------------------------------- toggleOpen: -> if @isClosed() then @open() else @close() @@ -703,7 +722,11 @@ class TreemaNode childrenContainer.append($(@addChildTemplate)) # this tends to break ACE editors within if @ordered and childrenContainer.sortable and not @settings.noSortable - childrenContainer.sortable?(deactivate: @orderDataFromUI) + childrenContainer.sortable?({ + deactivate: @orderDataFromUI + forcePlaceholderSize: true + placeholder: 'placeholder' + }) @refreshErrors() depth -= 1 if depth @@ -717,11 +740,16 @@ class TreemaNode for child in children treema = $(child).data('instance') continue unless treema?.data - treema.keyForParent = index - @childrenTreemas[index] = treema - @data[index] = treema.data + if $.isArray @data + treema.keyForParent = index + @childrenTreemas[index] = treema + @data[index] = treema.data + else + @childrenTreemas[treema.keyForParent] = treema + @data[treema.keyForParent] = treema.data index += 1 @flushChanges() + @broadcastChanges() close: (saveChildData=true) -> return unless @isOpen() @@ -775,19 +803,19 @@ class TreemaNode if not started if node in endNodes node.$el.addClass('treema-selected') - started = true + started = true continue node.$el.addClass('treema-selected') if started and (node in endNodes) - break + break lastSelected.removeClass('treema-last-selected') @$el.addClass('treema-last-selected') TreemaNode.didSelect = true #Save/restore state - addTrackedAction: (action)-> + addTrackedAction: (action) -> root = @getRoot() - return if root.trackingDisabled + return if root.trackingDisabled root.trackedActions.splice root.currentStateIndex, root.trackedActions.length - root.currentStateIndex root.trackedActions.push action root.currentStateIndex++ @@ -797,7 +825,7 @@ class TreemaNode enableTracking: -> @getRoot().trackingDisabled = false - + canUndo: -> return @getCurrentStateIndex() isnt 0 @@ -920,9 +948,9 @@ class TreemaNode @getRoot().trackedActions getCurrentStateIndex: -> @getRoot().currentStateIndex - + # Switching types or working schemas - + onSelectSchema: (e) => index = parseInt($(e.target).val()) workingSchema = @workingSchemas[index] @@ -952,7 +980,7 @@ class TreemaNode newNode = TreemaNode.make(null, settings, @parent, @keyForParent) @replaceNode(newNode) - + replaceNode: (newNode) -> newNode.tv4 = @tv4 newNode.keyForParent = @keyForParent if @keyForParent? @@ -981,7 +1009,7 @@ class TreemaNode @buildValueForDisplay(@getValEl().empty(), @getData()) @broadcastChanges() treema - + segregateChildTreema: (treema) -> treema.integrated = false delete @childrenTreemas[treema.keyForParent] @@ -1136,7 +1164,7 @@ class TreemaNode deleteRecursive: (path) -> path = @normalizePath(path) if path.length is 0 - return @remove() + return @remove() return @digDeeper(path, 'deleteRecursive', false, []) if @childrenTreemas? data = @data @@ -1157,7 +1185,7 @@ class TreemaNode parentPath = path parentData = @get parentPath childPath = parentPath - childPath += '/' unless parentPath is '/' + childPath += '/' unless parentPath is '/' if parentData[parentData.length-1] isnt newData for key, val of parentData @@ -1248,10 +1276,10 @@ class TreemaNode node getInputs: -> @getValEl().find('input, textarea') getSelectedTreemas: -> ($(el).data('instance') for el in @getRootEl().find('.treema-selected')) - getLastSelectedTreema: -> + getLastSelectedTreema: -> @getRoot().lastSelectedTreema - setLastSelectedTreema: (node) -> + setLastSelectedTreema: (node) -> @getRoot().lastSelectedTreema = node node?.$el.addClass('treema-last-selected') @@ -1283,13 +1311,13 @@ class TreemaNode rootSelected: -> $(document.activeElement).hasClass('treema-root') # to avoid naming conflict with "visible", "displaying". Visibility related to filter is denoted to "filterVisible" - setFilterVisible: (isFilterVisible)-> - if isFilterVisible - @$el.find('.treema-node').andSelf().removeClass(@treemaFilterHiddenClass) - else + setFilterVisible: (isFilterVisible) -> + if isFilterVisible + @$el.find('.treema-node').andSelf().removeClass(@treemaFilterHiddenClass) + else @$el.find('.treema-node').andSelf().addClass(@treemaFilterHiddenClass) - getFilterVisibleTreemas: -> + getFilterVisibleTreemas: -> ($(el).data('instance') for el in @getRootEl().find('.treema-node').not('.' + @treemaFilterHiddenClass)) isFilterVisible: -> !@$el.hasClass(@treemaFilterHiddenClass) @@ -1301,7 +1329,7 @@ class TreemaNode @scrolls.push {el: parent, scrollTop: parent.scrollTop(), scrollLeft: parent.scrollLeft()} break if parent.prop('tagName').toLowerCase() is 'body' parent = parent.parent() - + loadScrolls: -> return unless @scrolls for scroll in @scrolls @@ -1313,7 +1341,7 @@ class TreemaNode @saveScrolls() @getRootEl().focus() @loadScrolls() - + copyData: -> $.extend(null, {}, {'d': @data})['d'] updateMyAddButton: -> @$el.removeClass('treema-full') @@ -1331,13 +1359,13 @@ class TreemaNode tv4 = TreemaUtils.getGlobalTv4().freshApi() tv4.addSchema('#', schema) schema = @utils.resolveReference(schema, tv4) - + if schema.default? and not (options.data? or options.defaultData?) if $.type(schema.default) is 'object' options.data = {} # objects handle defaults uniquely else options.data = @utils.cloneDeep(schema.default) - + workingData = options.data or options.defaultData workingSchemas = options.workingSchemas or @utils.buildWorkingSchemas(schema, parent?.tv4) workingSchema = options.workingSchema or @utils.chooseWorkingSchema(workingData, workingSchemas, options.tv4) @@ -1346,24 +1374,24 @@ class TreemaNode type = 'null' if type is 'undefined' localClasses = if parent then parent.settings.nodeClasses else options.nodeClasses NodeClass = @getNodeClassForSchema(workingSchema, type, localClasses) - + # still to redo a bit... if parent for key, value of parent.settings continue if key in ['data', 'defaultData', 'schema'] options[key] = value - + options.workingSchema = workingSchema options.workingSchemas = workingSchemas options.keyForParent = keyForParent if keyForParent? newNode = new NodeClass(element, options, parent) newNode - + @massageData: (options, workingSchema) -> # do not allow data or default data to start out invalid with the working schema type, if possible schemaTypes = workingSchema.type or ['string', 'number', 'integer', 'object', 'array', 'boolean', 'null'] schemaTypes = [schemaTypes] unless $.type(schemaTypes) is 'array' - + # type can't tell between number and integer, so just treat them as the same if 'integer' in schemaTypes and 'number' not in schemaTypes schemaTypes.push 'number' @@ -1374,11 +1402,11 @@ class TreemaNode # if the data does not match the schema types if dataType isnt 'undefined' and dataType not in schemaTypes options.data = @defaultForType(schemaTypes[0]) - + # if there's no data or default data that works for the schema, reset it if dataType is 'undefined' and defaultDataType not in schemaTypes options.data = @defaultForType(schemaTypes[0]) - + @defaultForType: (type) -> TreemaNode.utils.defaultForType(type) @getNodeClassForSchema: (schema, def='string', localClasses=null) -> @@ -1414,7 +1442,7 @@ class TreemaNode @didSelect = false @changedTreemas = [] - filterChildren: (filter)-> + filterChildren: (filter) -> for keyForParent, treemaNode of @childrenTreemas treemaNode.setFilterVisible(!filter || filter(treemaNode, keyForParent)) diff --git a/src/core.coffee b/src/core.coffee index 8776be6..4e76c0e 100644 --- a/src/core.coffee +++ b/src/core.coffee @@ -377,9 +377,10 @@ do __init = -> canAddProperty: (key) -> return true unless @workingSchema.additionalProperties is false - return true if @workingSchema.properties[key]? + return true if @workingSchema.properties?[key]? if @workingSchema.patternProperties? - return true if RegExp(pattern).test(key) for pattern of @workingSchema.patternProperties + for pattern of @workingSchema.patternProperties + return true if RegExp(pattern).test(key) return false showBadPropertyError: (keyInput) -> diff --git a/src/extra.coffee b/src/extra.coffee index aafb544..33b0235 100644 --- a/src/extra.coffee +++ b/src/extra.coffee @@ -1,7 +1,7 @@ do -> TreemaNode.setNodeSubclass 'point2d', class Point2DNode extends TreemaNode valueClass: 'treema-point2d' - + buildValueForDisplay: (valEl, data) -> @buildValueForDisplaySimply(valEl, "(#{data.x}, #{data.y})") buildValueForEditing: (valEl, data) -> @@ -17,7 +17,7 @@ do -> TreemaNode.setNodeSubclass 'point3d', class Point3DNode extends TreemaNode valueClass: 'treema-point3d' - + buildValueForDisplay: (valEl, data) -> @buildValueForDisplaySimply(valEl, "(#{data.x}, #{data.y}, #{data.z})") @@ -153,13 +153,14 @@ do -> session.on('change', @saveChanges) @editor.setOptions({ maxLines: Infinity }) @editor.setTheme(@schema.aceTheme) if @schema.aceTheme? + @editor.$blockScrolling = Infinity # HACK: This gets the editor to be always on like I want, but which is unlike # most other nodes where there's an edit state and a view state. - toggleEdit: -> + toggleEdit: -> @initEditor(@getValEl()) unless @editor @deselectAll() - + buildValueForDisplay: (valEl) -> @initEditor(valEl) unless @editor buildValueForEditing: -> diff --git a/src/style/base.sass b/src/style/base.sass index e193adc..cd89717 100644 --- a/src/style/base.sass +++ b/src/style/base.sass @@ -1,6 +1,10 @@ @import "variables" +.treema-target-of-copy-paste + transform: translateX(10px) + .treema-node + transition: 0.1s ease-in-out transform user-select: none -webkit-user-select: none -moz-user-select: none @@ -198,4 +202,4 @@ display: none .treema-default-stub - opacity: 0.7 \ No newline at end of file + opacity: 0.7 diff --git a/src/utils.coffee b/src/utils.coffee index 76f8d87..6e6ce2a 100644 --- a/src/utils.coffee +++ b/src/utils.coffee @@ -50,13 +50,23 @@ TreemaUtils = (-> callback(path, data, workingSchema) # this actually works for both arrays and objects... - if @type(data) in ['array', 'object'] - for key, value of data + dataType = @type(data) + + if dataType in ['array', 'object'] + f = (key, value) => + value = data[key] childPath = path.slice() childPath += '.' if childPath childPath += key childSchema = @getChildSchema(key, workingSchema) @walk(value, childSchema, tv4, callback, childPath) + + if dataType is 'array' + for value, key in data + f(key, value) + else + for key, value of data + f(key, value) utils.getChildSchema = (key, schema) -> if @type(key) is 'string' diff --git a/test/callbacks/change.coffee b/test/callbacks/change.coffee index 2452f59..aed56b8 100644 --- a/test/callbacks/change.coffee +++ b/test/callbacks/change.coffee @@ -28,7 +28,6 @@ describe 'Change callback', -> schema: schema callbacks: change: -> - console.log 'change callback', arguments fired.f += 1 }) treema.build() diff --git a/test/canAddProperty.spec.coffee b/test/canAddProperty.spec.coffee new file mode 100644 index 0000000..646b156 --- /dev/null +++ b/test/canAddProperty.spec.coffee @@ -0,0 +1,14 @@ +describe 'canAddProperty', -> + it 'works when properties is not defined, additionalProperties is false, and patternProperties is defined', -> + schema = { + "type": "object", + "patternProperties": { + "^[a-z]+$": {} + }, + "additionalProperties": false + } + data = {} + treema = TreemaNode.make(null, {data: data, schema: schema}) + treema.build() + expect(treema.canAddProperty('test')).toBe(true) + expect(treema.canAddProperty('1234')).toBe(false) diff --git a/test/keyboard/delete-key.coffee b/test/keyboard/delete-key.coffee index beafa38..4d021cc 100644 --- a/test/keyboard/delete-key.coffee +++ b/test/keyboard/delete-key.coffee @@ -16,6 +16,7 @@ describe 'Delete key press', -> copy = $.extend(true, {}, original_data) treema = TreemaNode.make(null, {data: copy, schema: schema}) treema.build() + nameTreema = treema.childrenTreemas.name addressTreema = treema.childrenTreemas.address phoneTreema = treema.childrenTreemas.numbers @@ -49,7 +50,7 @@ describe 'Delete key press', -> expect(treema.childrenTreemas.name).toBeUndefined() expect(treema.childrenTreemas.address).toBeUndefined() - it 'removes single elements of a collection one at a time, then the collection itself', -> + xit 'removes single elements of a collection one at a time, then the collection itself', -> phoneTreema.open() phoneTreema.childrenTreemas[1].open() phoneTreema.childrenTreemas[0].select() diff --git a/test/keyboard/tab-key.coffee b/test/keyboard/tab-key.coffee index ddeebc9..7d5415b 100644 --- a/test/keyboard/tab-key.coffee +++ b/test/keyboard/tab-key.coffee @@ -80,3 +80,13 @@ describe 'Tab key press', -> phoneTreema.select() tabKeyPress(phoneTreema.$el) expect(phoneTreema.childrenTreemas[0].isEditing()).toBeTruthy() + + xit 'goes around in a loop', -> + # this test doesn't work because focus on the add button doesn't work in a testing condition... + $('body').append(treema.$el) + addressTreema.select() + tabKeyPress(treema.$el) # editing address + tabKeyPress($(document.activeElement)) # selecting add button + expect(nameTreema.isEditing()).toBeTruthy() + treema.$el.remove() + diff --git a/test/required.spec.coffee b/test/required.spec.coffee index 81d0a13..e9b6437 100644 --- a/test/required.spec.coffee +++ b/test/required.spec.coffee @@ -5,33 +5,33 @@ describe 'schema property "required"', -> "type": "object", "additionalProperties": false, "properties": { - "0": { type: "integer" }, - "1": { type: "string" }, - "2": { type: "number" }, - "3": { type: "null" }, - "4": { type: "boolean" }, - "5": { type: "array", items: { type: 'number', default: 42 } }, - "6": { type: "object" }, - "7": { 'default': 1337 } + "integer": { type: "integer" }, + "string": { type: "string" }, + "number": { type: "number" }, + "null": { type: "null" }, + "boolean": { type: "boolean" }, + "array": { type: "array", items: { type: 'number', default: 42 } }, + "object": { type: "object" }, + "def": { 'default': 1337 } }, - "required": ['0', '1', '2', '3','4','5','6','7'] + "required": ['integer', 'string', 'number', 'null','boolean','array','object','def'] } data = {} treema = TreemaNode.make(null, {data: data, schema: schema}) treema.build() it 'populates all required values with generic data', -> - expect(treema.get('/0')).toBe(0) - expect(treema.get('/1')).toBe('') - expect(treema.get('/2')).toBe(0) - expect(treema.get('/3')).toBe(null) - expect(treema.get('/4')).toBe(false) - expect(JSON.stringify(treema.get('/5'))).toBe(JSON.stringify([])) - expect(JSON.stringify(treema.get('/6'))).toBe(JSON.stringify({})) + expect(treema.get('/integer')).toBe(0) + expect(treema.get('/string')).toBe('') + expect(treema.get('/number')).toBe(0) + expect(treema.get('/null')).toBe(null) + expect(treema.get('/boolean')).toBe(false) + expect(JSON.stringify(treema.get('/array'))).toBe(JSON.stringify([])) + expect(JSON.stringify(treema.get('/object'))).toBe(JSON.stringify({})) it 'populates required values with defaults', -> - expect(treema.get('/7')).toBe(1337) - treema.childrenTreemas['5'].addNewChild() + expect(treema.get('/def')).toBe(1337) + treema.childrenTreemas['array'].addNewChild() expect(treema.$el.find('input').val()).toBe('42') describe 'schema property "required"', -> diff --git a/test/utils.spec.coffee b/test/utils.spec.coffee index 24ead5a..5136adb 100644 --- a/test/utils.spec.coffee +++ b/test/utils.spec.coffee @@ -98,6 +98,25 @@ describe 'utilities', -> expect(data in values).toBe(true) expect(data.key1 in values).toBe(true) expect(data.key2 in values).toBe(true) + + it 'traverses arrays', -> + schema = { + type: 'array' + items: { + type: 'object' + marker: true + } + } + + data = [{}] + foundIt = false + + TreemaNode.utils.walk data, schema, null, (path, data, schema) -> + if path is '0' + expect(schema.marker).toBe(true) + foundIt = true + + expect(foundIt).toBe(true) describe 'getChildSchema', -> it 'returns child schemas from properties', -> @@ -166,4 +185,4 @@ describe 'utilities', -> expect('number' in types).toBe(true) # Eventually might want more advanced behaviors, like smartly combining types from "allOf" or "oneOf" schemas. - # But for now this more naive combination behavior will do. \ No newline at end of file + # But for now this more naive combination behavior will do. diff --git a/treema-utils.js b/treema-utils.js index 2fd63f7..2a839e7 100644 --- a/treema-utils.js +++ b/treema-utils.js @@ -69,7 +69,8 @@ TreemaUtils = (function() { return rootData; }; utils.walk = function(data, schema, tv4, callback, path) { - var childPath, childSchema, key, value, workingSchema, workingSchemas, _ref, _results; + var dataType, f, key, value, workingSchema, workingSchemas, _i, _len, _results, _results1, + _this = this; if (path == null) { path = ''; } @@ -83,19 +84,34 @@ TreemaUtils = (function() { workingSchemas = this.buildWorkingSchemas(schema, tv4); workingSchema = this.chooseWorkingSchema(data, workingSchemas, tv4); callback(path, data, workingSchema); - if ((_ref = this.type(data)) === 'array' || _ref === 'object') { - _results = []; - for (key in data) { + dataType = this.type(data); + if (dataType === 'array' || dataType === 'object') { + f = function(key, value) { + var childPath, childSchema; value = data[key]; childPath = path.slice(); if (childPath) { childPath += '.'; } childPath += key; - childSchema = this.getChildSchema(key, workingSchema); - _results.push(this.walk(value, childSchema, tv4, callback, childPath)); + childSchema = _this.getChildSchema(key, workingSchema); + return _this.walk(value, childSchema, tv4, callback, childPath); + }; + if (dataType === 'array') { + _results = []; + for (key = _i = 0, _len = data.length; _i < _len; key = ++_i) { + value = data[key]; + _results.push(f(key, value)); + } + return _results; + } else { + _results1 = []; + for (key in data) { + value = data[key]; + _results1.push(f(key, value)); + } + return _results1; } - return _results; } }; utils.getChildSchema = function(key, schema) { diff --git a/treema-utils.js.map b/treema-utils.js.map index 3b0ae66..cdba2c5 100644 --- a/treema-utils.js.map +++ b/treema-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"treema-utils.js","sources":["src/utils.coffee"],"names":[],"mappings":"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","sourcesContent":["TreemaUtils = (->\n \n utils = {}\n \n utils.populateDefaults = (rootData, rootSchema, tv4) ->\n if rootSchema.default and not rootData\n rootData = @cloneDeep(rootSchema.default)\n \n @walk rootData, rootSchema, tv4, (path, data, schema) =>\n def = schema.default\n return unless @type(def) is 'object' and @type(data) is 'object'\n for key, value of def\n if data[key] is undefined\n data[key] = @cloneDeep(value)\n \n rootData\n \n utils.populateRequireds = (rootData, rootSchema, tv4) ->\n rootData ?= {}\n\n @walk rootData, rootSchema, tv4, (path, data, schema) =>\n return unless schema.required and @type(data) is 'object'\n for key in schema.required\n continue if data[key]?\n if schemaDefault = schema.default?[key]\n data[key] = @cloneDeep(schemaDefault)\n else\n childSchema = @getChildSchema(key, schema)\n workingSchema = @buildWorkingSchemas(childSchema, tv4)[0]\n schemaDefault = workingSchema.default\n if schemaDefault?\n data[key] = @cloneDeep(schemaDefault)\n else\n type = workingSchema.type\n if @type(type) is 'array' then type = type[0]\n if not type then type = 'string'\n data[key] = @defaultForType(type)\n\n rootData\n \n utils.walk = (data, schema, tv4, callback, path='') ->\n if not tv4\n tv4 = @getGlobalTv4().freshApi()\n tv4.addSchema('#', schema)\n tv4.addSchema(schema.id, schema) if schema.id\n \n workingSchemas = @buildWorkingSchemas(schema, tv4)\n workingSchema = @chooseWorkingSchema(data, workingSchemas, tv4)\n \n callback(path, data, workingSchema)\n \n # this actually works for both arrays and objects...\n if @type(data) in ['array', 'object']\n for key, value of data\n childPath = path.slice()\n childPath += '.' if childPath\n childPath += key\n childSchema = @getChildSchema(key, workingSchema)\n @walk(value, childSchema, tv4, callback, childPath)\n \n utils.getChildSchema = (key, schema) ->\n if @type(key) is 'string'\n for childKey, childSchema of schema.properties\n if childKey is key\n return childSchema \n for childKey, childSchema of schema.patternProperties\n if key.match(new RegExp(childKey))\n return childSchema\n if typeof schema.additionalProperties is 'object'\n return schema.additionalProperties \n \n if @type(key) is 'number'\n index = key\n if schema.items\n if Array.isArray(schema.items)\n if index < schema.items.length\n return schema.items[index]\n else if schema.additionalItems\n return schema.additionalItems\n else if schema.items\n return schema.items\n \n return {}\n \n # Working schemas -----------------------------------------------------------\n \n # Schemas can be flexible using combinatorial properties and references.\n # But it simplifies logic if schema props like $ref, allOf, anyOf, and oneOf\n # are flattened into a list of more straightforward user choices.\n # These simplifications are called working schemas.\n \n utils.buildWorkingSchemas = (schema, tv4) ->\n schema ?= {}\n baseSchema = @resolveReference(schema, tv4)\n return [schema] unless schema.allOf or schema.anyOf or schema.oneOf\n baseSchema = @cloneSchema(baseSchema)\n allOf = baseSchema.allOf\n anyOf = baseSchema.anyOf\n oneOf = baseSchema.oneOf\n delete baseSchema.allOf if baseSchema.allOf?\n delete baseSchema.anyOf if baseSchema.anyOf?\n delete baseSchema.oneOf if baseSchema.oneOf?\n \n if allOf?\n for schema in allOf\n @combineSchemas baseSchema, @resolveReference(schema, tv4)\n \n workingSchemas = []\n singularSchemas = []\n singularSchemas = singularSchemas.concat(anyOf) if anyOf?\n singularSchemas = singularSchemas.concat(oneOf) if oneOf?\n \n for singularSchema in singularSchemas\n singularSchema = @resolveReference(singularSchema, tv4)\n newBase = @cloneSchema(baseSchema)\n @combineSchemas(newBase, singularSchema)\n workingSchemas.push(newBase)\n \n workingSchemas = [baseSchema] if workingSchemas.length is 0\n workingSchemas\n \n utils.chooseWorkingSchema = (data, workingSchemas, tv4) ->\n return workingSchemas[0] if workingSchemas.length is 1\n tv4 ?= @getGlobalTv4()\n for schema in workingSchemas\n result = tv4.validateMultiple(data, schema)\n return schema if result.valid\n return workingSchemas[0]\n \n utils.resolveReference = (schema, tv4, scrubTitle=false) ->\n return schema unless schema.$ref?\n tv4 ?= @getGlobalTv4()\n resolved = tv4.getSchema(schema.$ref)\n unless resolved\n console.warn('could not resolve reference', schema.$ref, tv4.getMissingUris())\n resolved ?= {}\n delete resolved.title if scrubTitle and resolved.title?\n resolved\n \n utils.getGlobalTv4 = ->\n if typeof window isnt 'undefined'\n return window.tv4\n if typeof global isnt 'undefined'\n return global.tv4\n if typeof tv4 isnt 'undefined'\n return tv4\n \n # UTILITY UTILITIES\n # Normally I'd use jQuery or lodash for most of these, but this file should be completely library/context agnostic.\n # These are fairly simplified because data is assumed to not include non-plain objects.\n \n utils.cloneSchema = (schema) ->\n clone = {}\n clone[key] = value for key, value of schema\n clone\n \n utils.combineSchemas = (schema1, schema2) ->\n for key, value of schema2\n schema1[key] = value \n schema1\n \n utils.cloneDeep = (data) ->\n clone = data\n type = @type(data)\n if type is 'object'\n clone = {}\n if type is 'array'\n clone = []\n if type in ['object', 'array']\n for key, value of data\n clone[key] = @cloneDeep(value)\n return clone\n \n # http://arcturo.github.io/library/coffeescript/07_the_bad_parts.html\n utils.type = do ->\n classToType = {}\n for name in \"Boolean Number String Function Array Date RegExp Undefined Null\".split(\" \")\n classToType[\"[object \" + name + \"]\"] = name.toLowerCase()\n \n (obj) ->\n strType = Object::toString.call(obj)\n classToType[strType] or \"object\"\n\n utils.defaultForType = (type) ->\n {string:'', number:0, null: null, object: {}, integer: 0, boolean: false, array:[]}[type]\n \n # Export either to TreemaNode if it exists, or to module.exports for node\n\n if typeof TreemaNode isnt 'undefined'\n TreemaNode.utils = utils\n\n else if typeof module isnt 'undefined' and module.exports\n module.exports = utils\n \n else\n return utils\n\n)()\n"]} \ No newline at end of file +{"version":3,"sources":["src/utils.coffee"],"names":[],"mappings":"AAAA;;AAAA,GAAc,MAAC,EAAf;CAEE;CAAA,EAAQ,EAAR;CAAA,CAEA,CAAyB,EAApB,GAAoB,CAAC,CAAD,MAAzB;CACE;AAA8B,CAA9B,QAAa;CACX,EAAW,CAAC,EAAZ,GAAW,CAAqB;KADlC;CAAA,CAGgB,CAAhB,GAAiC,EAAjC,CAAkC,CAAlC;CACE;CAAA,QAAY;AACZ,GAAc,CAAd,CAAe,CAAf,EAAc;CAAd;OADA;AAEA;UAAA;yBAAA;CACE,EAAQ,CAAL,CAAa,CAAhB;CACE,EAAK,EAAQ,IAAD;MADd;CAAA;SADF;CAAA;sBAH+B;CAAjC,IAAiC;CAJV,UAWvB;CAbF,EAEyB;CAFzB,CAeA,CAA0B,EAArB,GAAqB,CAAC,CAAD,OAA1B;CACE;;GAAY,GAAZ;KAAA;CAAA,CAEgB,CAAhB,GAAiC,EAAjC,CAAkC,CAAlC;CACE;AAAA,KAAmC,CAAnC,EAAc;CAAd;OAAA;CACA;CAAA;YAAA;uBAAA;CACE,GAAY,IAAZ;CAAA;SAAA;CACA,EAAmC,CAAhC,CAAgC,CAAnC,OAAG;CACD,EAAK,EAAQ,IAAD;MADd;CAGE,CAAmC,CAArB,EAAC,CAAD,IAAd,IAAc;CAAd,CACkD,CAAlC,EAAC,KAAjB,CAAgB,EAAhB,MAAgB;CADhB,EAEgB,MAAa,CAA7B;CACA,GAAG,MAAH;CACE,EAAK,EAAQ,IAAD;MADd;CAGE,EAAO,CAAP,SAAoB;CACpB,GAAG,CAAC,EAAJ;CAA+B,EAAO,CAAP;aAD/B;AAEO,CAAP,GAAG,QAAH;CAAiB,EAAO,CAAP;aAFjB;CAAA,EAGK,EAAQ,SAAD;WAZhB;SAFF;CAAA;sBAF+B;CAAjC,IAAiC;CAHT,UAqBxB;CApCF,EAe0B;CAf1B,CAsCA,CAAa,CAAb,CAAK,CAAQ,GAAC;CACZ;OAAA;;GAD8C,GAAL;KACzC;AAAO,CAAP;CACE,GAAO,EAAP,EAAM;CAAN,CACmB,CAAhB,GAAH;CACA,GAAoC,EAApC;CAAA,EAAG,GAAiB,EAApB;OAHF;KAAA;CAAA,CAK8C,CAA7B,CAAjB,EAAiB,QAAjB,KAAiB;CALjB,CAM2C,CAA3B,CAAhB,UAAgB;CANhB,CAQe,EAAf;CARA,EAWW,CAAX;CAEA,IAAgB,EAAb;CACD,CAAU,CAAN,GAAJ,GAAK;CACH;CAAA,EAAQ,CAAK,CAAb;CAAA,EACY,CAAI,CAAJ,GAAZ;CACA,GAAoB,IAApB;CAAA,GAAa,KAAb;SAFA;CAAA,GAGa,IAAb;CAHA,CAImC,CAArB,EAAC,GAAf,KAAc;CACb,CAAY,CAAb,EAAC,GAAD;CANF,MAAI;CAQJ,GAAG,CAAY,CAAf,EAAG;AACD;cAAA;4BAAA;CACE,CAAO,CAAP;CADF;wBADF;MAAA;AAIE;WAAA;4BAAA;CACE,CAAO,CAAP;CADF;yBAJF;OATF;KAdW;CAtCb,EAsCa;CAtCb,CAoEA,CAAuB,EAAlB,CAAkB,GAAC,KAAxB;CACE;CAAA,EAAG,CAAH,CAAiB,GAAjB;CACE;CAAA;qCAAA;CACE,GAAG,CAAY,GAAf;CACE,gBAAO;SAFX;CAAA;CAGA;CAAA;sCAAA;CACE,EAAM,CAAH,EAAc,EAAjB;CACE,gBAAO;SAFX;CAAA,MAHA;AAMG,CAAH,GAAG,CAAsC,CAAzC,cAAG;CACD,KAAa,SAAN,KAAP;OARJ;KAAA;CAUA,EAAG,CAAH,CAAiB,GAAjB;CACE,EAAQ,EAAR;CACA,GAAG,CAAH;CACE,GAAG,CAAK,CAAe,CAApB,CAAH;CACE,EAAW,CAAR,EAAc,IAAjB;CACE,IAAoB,CAAP,aAAN;CACM,GAAP,EAFR;CAGE,KAAa,SAAb,IAAO;WAJX;CAKe,GAAP,CALR;CAME,KAAa,WAAN;SAPX;OAFF;KAVA;CAqBA,UAAO;CA1FT,EAoEuB;CApEvB,CAmGA,CAA4B,EAAvB,CAAuB,GAAC,UAA7B;CACE;;GAAU,GAAV;KAAA;CAAA,CACuC,CAA1B,CAAb,EAAa,IAAb,MAAa;AACb,KAAuB,CAAM;CAA7B,KAAO;KAFP;CAAA,EAGa,CAAb,OAAa;CAHb,EAIQ,CAAR,MAAkB;CAJlB,EAKQ,CAAR,MAAkB;CALlB,EAMQ,CAAR,MAAkB;CAClB;AAAA,UAAiB;KAPjB;CAQA;AAAA,UAAiB;KARjB;CASA;AAAA,UAAiB;KATjB;CAWA;AACE;2BAAA;CACE,CAA4B,EAA3B,EAA2B,EAA5B,QAA4B;CAD9B,MADF;KAXA;CAAA,EAeiB,CAAjB;CAfA,EAgBkB,CAAlB;CACA;CAAA,EAAkB,GAAlB;KAjBA;CAkBA;CAAA,EAAkB,GAAlB;KAlBA;AAoBA;2CAAA;CACE,CAAmD,CAAlC,CAAC,EAAlB,UAAiB;CAAjB,EACU,CAAC,EAAX,IAAU;CADV,CAEyB,EAAxB,EAAD;CAFA,GAGA,UAAc;CAJhB,IApBA;CA0BA,IAA0D,CAAzB,QAAc;CAA/C,EAAiB,GAAjB,IAAiB,IAAjB;KA1BA;CAD0B,UA4B1B;CA/HF,EAmG4B;CAnG5B,CAiIA,CAA4B,EAAvB,IAAwB,KAAD,KAA5B;CACE;CAAA,IAAqD,CAAzB,QAAc;CAA1C,YAAO,CAAe;KAAtB;;CACQ,EAAD,CAAC,EAAR,MAAO;KADP;AAEA;kCAAA;CACE,CAAoC,CAA3B,GAAT,UAAS;CACT,GAAiB,CAAjB;CAAA,cAAO;OAFT;CAAA,IAFA;CAKA,UAAO,GAAe;CAvIxB,EAiI4B;CAjI5B,CAyIA,CAAyB,EAApB,CAAoB,GAAC,CAAD,MAAzB;CACE;;GADgD,GAAX;KACrC;CAAA;CAAA,YAAO;KAAP;;CACQ,EAAD,CAAC,EAAR,MAAO;KADP;CAAA,EAEW,CAAX,EAA+B,EAA/B,CAAW;AACJ,CAAP;CACE,CAA4C,CAAgB,CAA5D,GAAO,OAAkD,eAAzD;KAJF;;GAKY,GAAZ;KALA;CAMA,SAAyB,cAAzB;AAAA,QAAe;KANf;CADuB,UAQvB;CAjJF,EAyIyB;CAzIzB,CAmJA,CAAqB,EAAhB,IAAgB,GAArB;AACK,CAAH,IAAsB,CAAnB,KAAH;CACE,KAAa,OAAN;KADT;AAEG,CAAH,IAAsB,CAAnB,KAAH;CACE,KAAa,OAAN;KAHT;AAIG,CAAH,EAAG,CAAH,CAAmB,CAAhB,KAAH;CACE,YAAO;KANU;CAnJrB,EAmJqB;CAnJrB,CA+JA,CAAoB,EAAf,CAAe,GAAC,EAArB;CACE;CAAA,EAAQ,CAAR;AACA;0BAAA;CAAA,EAAM,GAAN;CAAA,IADA;CADkB,UAGlB;CAlKF,EA+JoB;CA/JpB,CAoKA,CAAuB,EAAlB,EAAkB,EAAC,KAAxB;CACE;AAAA;2BAAA;CACE,EAAQ,EAAR,EAAQ;CADV;CADqB,UAGrB;CAvKF,EAoKuB;CApKvB,CAyKA,CAAkB,EAAb,IAAL;CACE;CAAA,EAAQ,CAAR;CAAA,EACO,CAAP;CACA,IAAW,GAAX;CACE,EAAQ,EAAR;KAHF;CAIA,IAAW,EAAX;CACE,EAAQ,EAAR;KALF;CAMA,IAAY,EAAZ,CAAG;AACD;0BAAA;CACE,EAAM,CAAQ,CAAR,GAAN,CAAa;CADf,MADF;KANA;CASA,UAAO;CAnLT,EAyKkB;CAzKlB,CAsLA,CAAgB,CAAhB,CAAK,IAAW;CACd;CAAA,EAAc,CAAd;CACA;CAAA;sBAAA;CACE,EAAyB,CAAb,EAAZ,IAAY;CADd,IADA;GAIA,MAAC,EAAD;CACE;CAAA,EAAU,GAAV,EAA0B,CAAR;CACN,GAAY,GAAZ,MAAZ;CAPY,IAKd;CALc;CAtLhB,CA+LA,CAAuB,EAAlB,IAAmB,KAAxB;WACE;CAAA,CAAQ,IAAP;CAAD,CAAmB,IAAP;CAAZ,CAA4B,EAA5B,EAAsB;CAAtB,CAA0C,IAAR;CAAlC,CAAuD,IAAT;CAA9C,CAAmE,GAAnE,CAA0D;CAA1D,CAAgF,GAAN;CAAU;CAhMtF,EA+LuB;AAKpB,CAAH,GAAG,CAAuB,CAAvB,KAAH;CACa,EAAQ,EAAnB,KAAU,CAAV;AAEM,IAHR,CAG2B,CAH3B,KAGQ;CACC,EAAU,GAAX,CAAN;IAJF;CAOE,UAAO;GA7MI;CAAA","file":"treema-utils.js","sourcesContent":["TreemaUtils = (->\n \n utils = {}\n \n utils.populateDefaults = (rootData, rootSchema, tv4) ->\n if rootSchema.default and not rootData\n rootData = @cloneDeep(rootSchema.default)\n \n @walk rootData, rootSchema, tv4, (path, data, schema) =>\n def = schema.default\n return unless @type(def) is 'object' and @type(data) is 'object'\n for key, value of def\n if data[key] is undefined\n data[key] = @cloneDeep(value)\n \n rootData\n \n utils.populateRequireds = (rootData, rootSchema, tv4) ->\n rootData ?= {}\n\n @walk rootData, rootSchema, tv4, (path, data, schema) =>\n return unless schema.required and @type(data) is 'object'\n for key in schema.required\n continue if data[key]?\n if schemaDefault = schema.default?[key]\n data[key] = @cloneDeep(schemaDefault)\n else\n childSchema = @getChildSchema(key, schema)\n workingSchema = @buildWorkingSchemas(childSchema, tv4)[0]\n schemaDefault = workingSchema.default\n if schemaDefault?\n data[key] = @cloneDeep(schemaDefault)\n else\n type = workingSchema.type\n if @type(type) is 'array' then type = type[0]\n if not type then type = 'string'\n data[key] = @defaultForType(type)\n\n rootData\n \n utils.walk = (data, schema, tv4, callback, path='') ->\n if not tv4\n tv4 = @getGlobalTv4().freshApi()\n tv4.addSchema('#', schema)\n tv4.addSchema(schema.id, schema) if schema.id\n \n workingSchemas = @buildWorkingSchemas(schema, tv4)\n workingSchema = @chooseWorkingSchema(data, workingSchemas, tv4)\n \n callback(path, data, workingSchema)\n \n # this actually works for both arrays and objects...\n dataType = @type(data)\n \n if dataType in ['array', 'object']\n f = (key, value) =>\n value = data[key]\n childPath = path.slice()\n childPath += '.' if childPath\n childPath += key\n childSchema = @getChildSchema(key, workingSchema)\n @walk(value, childSchema, tv4, callback, childPath)\n \n if dataType is 'array'\n for value, key in data\n f(key, value)\n else\n for key, value of data\n f(key, value)\n \n utils.getChildSchema = (key, schema) ->\n if @type(key) is 'string'\n for childKey, childSchema of schema.properties\n if childKey is key\n return childSchema \n for childKey, childSchema of schema.patternProperties\n if key.match(new RegExp(childKey))\n return childSchema\n if typeof schema.additionalProperties is 'object'\n return schema.additionalProperties \n \n if @type(key) is 'number'\n index = key\n if schema.items\n if Array.isArray(schema.items)\n if index < schema.items.length\n return schema.items[index]\n else if schema.additionalItems\n return schema.additionalItems\n else if schema.items\n return schema.items\n \n return {}\n \n # Working schemas -----------------------------------------------------------\n \n # Schemas can be flexible using combinatorial properties and references.\n # But it simplifies logic if schema props like $ref, allOf, anyOf, and oneOf\n # are flattened into a list of more straightforward user choices.\n # These simplifications are called working schemas.\n \n utils.buildWorkingSchemas = (schema, tv4) ->\n schema ?= {}\n baseSchema = @resolveReference(schema, tv4)\n return [schema] unless schema.allOf or schema.anyOf or schema.oneOf\n baseSchema = @cloneSchema(baseSchema)\n allOf = baseSchema.allOf\n anyOf = baseSchema.anyOf\n oneOf = baseSchema.oneOf\n delete baseSchema.allOf if baseSchema.allOf?\n delete baseSchema.anyOf if baseSchema.anyOf?\n delete baseSchema.oneOf if baseSchema.oneOf?\n \n if allOf?\n for schema in allOf\n @combineSchemas baseSchema, @resolveReference(schema, tv4)\n \n workingSchemas = []\n singularSchemas = []\n singularSchemas = singularSchemas.concat(anyOf) if anyOf?\n singularSchemas = singularSchemas.concat(oneOf) if oneOf?\n \n for singularSchema in singularSchemas\n singularSchema = @resolveReference(singularSchema, tv4)\n newBase = @cloneSchema(baseSchema)\n @combineSchemas(newBase, singularSchema)\n workingSchemas.push(newBase)\n \n workingSchemas = [baseSchema] if workingSchemas.length is 0\n workingSchemas\n \n utils.chooseWorkingSchema = (data, workingSchemas, tv4) ->\n return workingSchemas[0] if workingSchemas.length is 1\n tv4 ?= @getGlobalTv4()\n for schema in workingSchemas\n result = tv4.validateMultiple(data, schema)\n return schema if result.valid\n return workingSchemas[0]\n \n utils.resolveReference = (schema, tv4, scrubTitle=false) ->\n return schema unless schema.$ref?\n tv4 ?= @getGlobalTv4()\n resolved = tv4.getSchema(schema.$ref)\n unless resolved\n console.warn('could not resolve reference', schema.$ref, tv4.getMissingUris())\n resolved ?= {}\n delete resolved.title if scrubTitle and resolved.title?\n resolved\n \n utils.getGlobalTv4 = ->\n if typeof window isnt 'undefined'\n return window.tv4\n if typeof global isnt 'undefined'\n return global.tv4\n if typeof tv4 isnt 'undefined'\n return tv4\n \n # UTILITY UTILITIES\n # Normally I'd use jQuery or lodash for most of these, but this file should be completely library/context agnostic.\n # These are fairly simplified because data is assumed to not include non-plain objects.\n \n utils.cloneSchema = (schema) ->\n clone = {}\n clone[key] = value for key, value of schema\n clone\n \n utils.combineSchemas = (schema1, schema2) ->\n for key, value of schema2\n schema1[key] = value \n schema1\n \n utils.cloneDeep = (data) ->\n clone = data\n type = @type(data)\n if type is 'object'\n clone = {}\n if type is 'array'\n clone = []\n if type in ['object', 'array']\n for key, value of data\n clone[key] = @cloneDeep(value)\n return clone\n \n # http://arcturo.github.io/library/coffeescript/07_the_bad_parts.html\n utils.type = do ->\n classToType = {}\n for name in \"Boolean Number String Function Array Date RegExp Undefined Null\".split(\" \")\n classToType[\"[object \" + name + \"]\"] = name.toLowerCase()\n \n (obj) ->\n strType = Object::toString.call(obj)\n classToType[strType] or \"object\"\n\n utils.defaultForType = (type) ->\n {string:'', number:0, null: null, object: {}, integer: 0, boolean: false, array:[]}[type]\n \n # Export either to TreemaNode if it exists, or to module.exports for node\n\n if typeof TreemaNode isnt 'undefined'\n TreemaNode.utils = utils\n\n else if typeof module isnt 'undefined' and module.exports\n module.exports = utils\n \n else\n return utils\n\n)()\n"]} \ No newline at end of file diff --git a/treema.css b/treema.css index 83df9df..b8ede51 100644 --- a/treema.css +++ b/treema.css @@ -1,4 +1,8 @@ +.treema-target-of-copy-paste { + transform: translateX(10px); } + .treema-node { + transition: 0.1s ease-in-out transform; user-select: none; -webkit-user-select: none; -moz-user-select: none; diff --git a/treema.js b/treema.js index 9ef818c..b32b0da 100644 --- a/treema.js +++ b/treema.js @@ -1,262 +1,4 @@ -(function() { - var WebSocket = window.WebSocket || window.MozWebSocket; - var br = window.brunch = (window.brunch || {}); - var ar = br['auto-reload'] = (br['auto-reload'] || {}); - if (!WebSocket || ar.disabled) return; - - var cacheBuster = function(url){ - var date = Math.round(Date.now() / 1000).toString(); - url = url.replace(/(\&|\\?)cacheBuster=\d*/, ''); - return url + (url.indexOf('?') >= 0 ? '&' : '?') +'cacheBuster=' + date; - }; - - var reloaders = { - page: function(){ - window.location.reload(true); - }, - - stylesheet: function(){ - [].slice - .call(document.querySelectorAll('link[rel="stylesheet"]')) - .filter(function(link){ - return (link != null && link.href != null); - }) - .forEach(function(link) { - link.href = cacheBuster(link.href); - }); - } - }; - var port = ar.port || 9485; - var host = br.server || window.location.hostname; - - var connect = function(){ - var connection = new WebSocket('ws://' + host + ':' + port); - connection.onmessage = function(event){ - if (ar.disabled) return; - var message = event.data; - var reloader = reloaders[message] || reloaders.page; - reloader(); - }; - connection.onerror = function(){ - if (connection.readyState) connection.close(); - }; - connection.onclose = function(){ - window.setTimeout(connect, 1000); - }; - }; - connect(); -})(); - -;(function(e){if("function"==typeof bootstrap)bootstrap("jade",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeJade=e}else"undefined"!=typeof window?window.jade=e():global.jade=e()})(function(){var define,ses,bootstrap,module,exports; -return (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o