mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-30 10:56:53 -05:00
Added a delta subview for displaying deltas of schema'd data.
This commit is contained in:
parent
721648dadf
commit
f2d21b960f
6 changed files with 211 additions and 1 deletions
89
app/lib/deltas.coffee
Normal file
89
app/lib/deltas.coffee
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
# path: an array of indexes to navigate into a JSON object
|
||||||
|
# left:
|
||||||
|
|
||||||
|
module.exports.interpretDelta = (delta, path, left, schema) ->
|
||||||
|
# takes a single delta and converts into an object that can be
|
||||||
|
# easily formatted into something human readable.
|
||||||
|
|
||||||
|
betterDelta = { action:'???', delta: delta }
|
||||||
|
|
||||||
|
betterPath = []
|
||||||
|
parentLeft = left
|
||||||
|
parentSchema = schema
|
||||||
|
for key in path
|
||||||
|
# TODO: A smarter way of getting child schemas
|
||||||
|
childSchema = parentSchema?.items or parentSchema?.properties?[key] or {}
|
||||||
|
childLeft = parentLeft?[key]
|
||||||
|
betterKey = null
|
||||||
|
betterKey ?= childLeft.name or childLeft.id if childLeft
|
||||||
|
betterKey ?= "#{childSchema.title} ##{key+1}" if childSchema.title and _.isNumber(key)
|
||||||
|
betterKey ?= "#{childSchema.title}" if childSchema.title
|
||||||
|
betterKey ?= _.string.titleize key
|
||||||
|
betterPath.push betterKey
|
||||||
|
parentLeft = childLeft
|
||||||
|
parentSchema = childSchema
|
||||||
|
|
||||||
|
betterDelta.path = betterPath.join(' :: ')
|
||||||
|
betterDelta.schema = childSchema
|
||||||
|
betterDelta.left = childLeft
|
||||||
|
betterDelta.right = jsondiffpatch.patch childLeft, delta
|
||||||
|
|
||||||
|
if _.isArray(delta) and delta.length is 1
|
||||||
|
betterDelta.action = 'added'
|
||||||
|
betterDelta.newValue = delta[0]
|
||||||
|
|
||||||
|
if _.isArray(delta) and delta.length is 2
|
||||||
|
betterDelta.action = 'modified'
|
||||||
|
betterDelta.oldValue = delta[0]
|
||||||
|
betterDelta.newValue = delta[1]
|
||||||
|
|
||||||
|
if _.isArray(delta) and delta.length is 3 and delta[1] is 0 and delta[2] is 0
|
||||||
|
betterDelta.action = 'deleted'
|
||||||
|
betterDelta.oldValue = delta[0]
|
||||||
|
|
||||||
|
if _.isPlainObject(delta) and delta._t is 'a'
|
||||||
|
betterDelta.action = 'modified-array'
|
||||||
|
|
||||||
|
if _.isPlainObject(delta) and delta._t isnt 'a'
|
||||||
|
betterDelta.action = 'modified-object'
|
||||||
|
|
||||||
|
if _.isArray(delta) and delta.length is 3 and delta[1] is 0 and delta[2] is 3
|
||||||
|
betterDelta.action = 'moved-index'
|
||||||
|
betterDelta.destinationIndex = delta[1]
|
||||||
|
|
||||||
|
if _.isArray(delta) and delta.length is 3 and delta[1] is 0 and delta[2] is 2
|
||||||
|
betterDelta.action = 'text-diff'
|
||||||
|
betterDelta.unidiff = delta[0]
|
||||||
|
left = betterDelta.left.trim().split('\n')
|
||||||
|
right = betterDelta.right.trim().split('\n')
|
||||||
|
shifted = popped = false
|
||||||
|
while left.length > 5 and right.length > 5 and left[0] is right[0] and left[1] is right[1]
|
||||||
|
left.shift()
|
||||||
|
right.shift()
|
||||||
|
shifted = true
|
||||||
|
while left.length > 5 and right.length > 5 and left[left.length-1] is right[right.length-1] and left[left.length-2] is right[right.length-2]
|
||||||
|
left.pop()
|
||||||
|
right.pop()
|
||||||
|
popped = true
|
||||||
|
left.push('...') and right.push('...') if popped
|
||||||
|
left.unshift('...') and right.unshift('...') if shifted
|
||||||
|
betterDelta.trimmedLeft = left.join('\n')
|
||||||
|
betterDelta.trimmedRight = right.join('\n')
|
||||||
|
|
||||||
|
|
||||||
|
betterDelta
|
||||||
|
|
||||||
|
module.exports.flattenDelta = flattenDelta = (delta, path=null) ->
|
||||||
|
# takes a single delta and returns an array of deltas
|
||||||
|
|
||||||
|
path ?= []
|
||||||
|
|
||||||
|
return [{path:path, delta:delta}] if _.isArray delta
|
||||||
|
|
||||||
|
results = []
|
||||||
|
affectingArray = delta._t is 'a'
|
||||||
|
for index, childDelta of delta
|
||||||
|
continue if index is '_t'
|
||||||
|
index = parseInt(index.replace('_', '')) if affectingArray
|
||||||
|
results = results.concat flattenDelta(childDelta, path.concat([index]))
|
||||||
|
results
|
|
@ -216,5 +216,10 @@ class CocoModel extends Backbone.Model
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
getDelta: ->
|
||||||
|
jsd = jsondiffpatch.create({
|
||||||
|
objectHash: (obj) -> obj.name || obj.id || obj._id || JSON.stringify(_.keys(obj))
|
||||||
|
})
|
||||||
|
jsd.diff @_revertAttributes, @attributes
|
||||||
|
|
||||||
module.exports = CocoModel
|
module.exports = CocoModel
|
||||||
|
|
35
app/styles/editor/delta.sass
Normal file
35
app/styles/editor/delta.sass
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#delta-list-view
|
||||||
|
width: 600px
|
||||||
|
.panel-heading
|
||||||
|
font-size: 13px
|
||||||
|
padding: 4px
|
||||||
|
.row
|
||||||
|
padding: 5px 10px
|
||||||
|
|
||||||
|
.delta-added
|
||||||
|
border-color: green
|
||||||
|
strong
|
||||||
|
color: green
|
||||||
|
.panel-heading
|
||||||
|
background-color: lighten(green, 70%)
|
||||||
|
|
||||||
|
.delta-modified
|
||||||
|
border-color: darkgoldenrod
|
||||||
|
strong
|
||||||
|
color: darkgoldenrod
|
||||||
|
.panel-heading
|
||||||
|
background-color: lighten(darkgoldenrod, 40%)
|
||||||
|
|
||||||
|
.delta-text-diff
|
||||||
|
border-color: blue
|
||||||
|
strong
|
||||||
|
color: blue
|
||||||
|
.panel-heading
|
||||||
|
background-color: lighten(blue, 45%)
|
||||||
|
|
||||||
|
.delta-deleted
|
||||||
|
border-color: red
|
||||||
|
strong
|
||||||
|
color: red
|
||||||
|
.panel-heading
|
||||||
|
background-color: lighten(red, 42%)
|
35
app/templates/editor/delta.jade
Normal file
35
app/templates/editor/delta.jade
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
- var i = 0
|
||||||
|
.panel-group#accordion
|
||||||
|
for delta in deltas
|
||||||
|
.delta.panel.panel-default(class='delta-'+delta.action)
|
||||||
|
.panel-heading
|
||||||
|
if delta.action === 'added'
|
||||||
|
strong(data-i18n="delta.added") Added
|
||||||
|
if delta.action === 'modified'
|
||||||
|
strong(data-i18n="delta.modified") Modified
|
||||||
|
if delta.action === 'deleted'
|
||||||
|
strong(data-i18n="delta.deleted") Deleted
|
||||||
|
if delta.action === 'moved-index'
|
||||||
|
strong(data-i18n="delta.modified_array") Moved Index
|
||||||
|
if delta.action === 'text-diff'
|
||||||
|
strong(data-i18n="delta.text_diff") Text Diff
|
||||||
|
span
|
||||||
|
a(data-toggle="collapse" data-parent="#accordion" href="#collapse-"+i)
|
||||||
|
span= delta.path
|
||||||
|
|
||||||
|
.panel-collapse.collapse(id="collapse-"+i)
|
||||||
|
.panel-body.row
|
||||||
|
if delta.action === 'added'
|
||||||
|
.new-value.col-md-12= delta.right
|
||||||
|
if delta.action === 'modified'
|
||||||
|
.old-value.col-md-6= delta.left
|
||||||
|
.new-value.col-md-6= delta.right
|
||||||
|
if delta.action === 'deleted'
|
||||||
|
.col-md-12
|
||||||
|
div.old-value= delta.left
|
||||||
|
if delta.action === 'text-diff'
|
||||||
|
.col-md-6
|
||||||
|
pre= delta.trimmedLeft
|
||||||
|
.col-md-6
|
||||||
|
pre= delta.trimmedRight
|
||||||
|
- i += 1
|
43
app/views/editor/delta.coffee
Normal file
43
app/views/editor/delta.coffee
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
CocoView = require 'views/kinds/CocoView'
|
||||||
|
template = require 'templates/editor/delta'
|
||||||
|
deltaLib = require 'lib/deltas'
|
||||||
|
|
||||||
|
module.exports = class DeltaListView extends CocoView
|
||||||
|
id: "delta-list-view"
|
||||||
|
template: template
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super(options)
|
||||||
|
@delta = options.delta
|
||||||
|
@schema = options.schema or {}
|
||||||
|
@left = options.left
|
||||||
|
|
||||||
|
getRenderData: ->
|
||||||
|
c = super()
|
||||||
|
deltas = deltaLib.flattenDelta @delta
|
||||||
|
deltas = (deltaLib.interpretDelta(d.delta, d.path, @left, @schema) for d in deltas)
|
||||||
|
c.deltas = deltas
|
||||||
|
@processedDeltas = deltas
|
||||||
|
c
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
deltas = @$el.find('.delta')
|
||||||
|
for delta, i in deltas
|
||||||
|
deltaEl = $(delta)
|
||||||
|
deltaData = @processedDeltas[i]
|
||||||
|
console.log 'delta', deltaEl, deltaData
|
||||||
|
if _.isObject(deltaData.left) and leftEl = deltaEl.find('.old-value')
|
||||||
|
options =
|
||||||
|
data: deltaData.left
|
||||||
|
schema: deltaData.schema
|
||||||
|
readOnly: true
|
||||||
|
treema = TreemaNode.make(leftEl, options)
|
||||||
|
treema.build()
|
||||||
|
|
||||||
|
if _.isObject(deltaData.right) and rightEl = deltaEl.find('.old-value')
|
||||||
|
options =
|
||||||
|
data: deltaData.right
|
||||||
|
schema: deltaData.schema
|
||||||
|
readOnly: true
|
||||||
|
treema = TreemaNode.make(rightEl, options)
|
||||||
|
treema.build()
|
|
@ -52,6 +52,9 @@
|
||||||
},
|
},
|
||||||
"underscore.string": {
|
"underscore.string": {
|
||||||
"main": "lib/underscore.string.js"
|
"main": "lib/underscore.string.js"
|
||||||
|
},
|
||||||
|
"jsondiffpatch": {
|
||||||
|
"main": ["build/bundle-full.js", "build/formatters.js", "src/formatters/html.css"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue