2014-04-09 19:09:35 -04:00
CocoView = require ' views/kinds/CocoView '
template = require ' templates/editor/delta '
2014-04-12 00:11:52 -04:00
deltasLib = require ' lib/deltas '
2014-04-09 19:09:35 -04:00
2014-04-12 00:11:52 -04:00
TEXTDIFF_OPTIONS =
baseTextName: " Old "
newTextName: " New "
contextSize: 5
viewType: 1
2014-09-22 17:05:13 -04:00
2014-04-12 00:11:52 -04:00
module.exports = class DeltaView extends CocoView
2014-09-22 17:05:13 -04:00
2014-05-08 13:54:39 -04:00
# ##
2014-09-22 17:05:13 -04:00
Takes a CocoModel instance ( model ) and displays changes since the
2014-05-08 13:54:39 -04:00
last save ( attributes vs _revertAttributes ) .
2014-09-22 17:05:13 -04:00
2014-05-08 13:54:39 -04:00
* If headModel is included , will look for and display conflicts with the changes in model .
* If comparisonModel is included , will show deltas between model and comparisonModel instead
of changes within model itself .
2014-09-22 17:05:13 -04:00
2014-05-08 13:54:39 -04:00
# ##
2014-09-22 17:05:13 -04:00
2014-04-09 22:07:44 -04:00
@deltaCounter: 0
2014-07-04 20:54:30 -04:00
className: ' delta-view '
2014-04-09 19:09:35 -04:00
template: template
constructor: (options) ->
super ( options )
2014-05-08 13:54:39 -04:00
@expandedDeltas = [ ]
@skipPaths = options . skipPaths
2014-09-22 17:05:13 -04:00
2014-05-08 13:54:39 -04:00
for modelName in [ ' model ' , ' headModel ' , ' comparisonModel ' ]
2014-07-04 14:46:33 -04:00
@ [ modelName ] = options [ modelName ]
2014-07-15 14:23:00 -04:00
continue unless @ [ modelName ] and options . loadModels
2014-07-14 19:37:10 -04:00
if not @ [ modelName ] . isLoaded
@ [ modelName ] = @ supermodel . loadModel ( @ [ modelName ] , ' document ' ) . model
2014-09-22 17:05:13 -04:00
2014-05-08 13:54:39 -04:00
@ buildDeltas ( ) if @ supermodel . finished ( )
2014-09-22 17:05:13 -04:00
2014-05-08 13:54:39 -04:00
onLoaded: ->
@ buildDeltas ( )
super ( )
2014-09-22 17:05:13 -04:00
2014-05-08 13:54:39 -04:00
buildDeltas: ->
if @ comparisonModel
@expandedDeltas = @ model . getExpandedDeltaWith ( @ comparisonModel )
else
@expandedDeltas = @ model . getExpandedDelta ( )
2014-05-30 16:40:38 -04:00
[ @ expandedDeltas , @ skippedDeltas ] = @ filterDeltas ( @ expandedDeltas )
2014-09-22 17:05:13 -04:00
2014-04-12 00:11:52 -04:00
if @ headModel
@headDeltas = @ headModel . getExpandedDelta ( )
2014-05-30 16:40:38 -04:00
@headDeltas = @ filterDeltas ( @ headDeltas ) [ 0 ]
2014-04-12 00:11:52 -04:00
@conflicts = deltasLib . getConflicts ( @ headDeltas , @ expandedDeltas )
2014-04-09 19:09:35 -04:00
2014-05-30 16:40:38 -04:00
filterDeltas: (deltas) ->
return [ deltas , [ ] ] unless @ skipPaths
2014-05-08 13:54:39 -04:00
for path , i in @ skipPaths
@ skipPaths [ i ] = [ path ] if _ . isString ( path )
newDeltas = [ ]
2014-05-30 16:40:38 -04:00
skippedDeltas = [ ]
for delta in deltas
2014-05-08 13:54:39 -04:00
skip = false
for skipPath in @ skipPaths
if _ . isEqual _ . first ( delta . dataPath , skipPath . length ) , skipPath
skip = true
break
2014-05-30 16:40:38 -04:00
if skip then skippedDeltas . push delta else newDeltas . push delta
[ newDeltas , skippedDeltas ]
2014-05-08 13:54:39 -04:00
2014-04-09 19:09:35 -04:00
getRenderData: ->
c = super ( )
2014-04-12 00:11:52 -04:00
c.deltas = @ expandedDeltas
c.counter = DeltaView . deltaCounter
2014-04-17 17:39:52 -04:00
DeltaView . deltaCounter += @ expandedDeltas . length
2014-04-09 19:09:35 -04:00
c
2014-09-22 17:05:13 -04:00
2014-04-09 19:09:35 -04:00
afterRender: ->
2014-04-12 00:11:52 -04:00
deltas = @ $el . find ( ' .details ' )
2014-04-09 19:09:35 -04:00
for delta , i in deltas
deltaEl = $ ( delta )
2014-04-12 00:11:52 -04:00
deltaData = @ expandedDeltas [ i ]
@ expandDetails ( deltaEl , deltaData )
2014-09-22 17:05:13 -04:00
2014-04-12 00:11:52 -04:00
conflictDeltas = @ $el . find ( ' .conflict-details ' )
conflicts = ( delta . conflict for delta in @ expandedDeltas when delta . conflict )
for delta , i in conflictDeltas
deltaEl = $ ( delta )
deltaData = conflicts [ i ]
@ expandDetails ( deltaEl , deltaData )
2014-09-22 17:05:13 -04:00
2014-04-12 00:11:52 -04:00
expandDetails: (deltaEl, deltaData) ->
2014-05-30 16:40:38 -04:00
treemaOptions = { schema: deltaData . schema or { } , readOnly: true }
2014-09-22 17:05:13 -04:00
2014-04-12 00:11:52 -04:00
if _ . isObject ( deltaData . left ) and leftEl = deltaEl . find ( ' .old-value ' )
options = _ . defaults { data: deltaData . left } , treemaOptions
2014-10-20 19:13:56 -04:00
try
TreemaNode . make ( leftEl , options ) . build ( )
catch error
console . error " Couldn ' t show left details Treema for " , deltaData . left , treemaOptions
2014-09-22 17:05:13 -04:00
2014-04-12 00:11:52 -04:00
if _ . isObject ( deltaData . right ) and rightEl = deltaEl . find ( ' .new-value ' )
options = _ . defaults { data: deltaData . right } , treemaOptions
2014-10-20 19:13:56 -04:00
try
TreemaNode . make ( rightEl , options ) . build ( )
catch error
console . error " Couldn ' t show right details Treema for " , deltaData . right , treemaOptions
2014-09-22 17:05:13 -04:00
2014-04-12 00:11:52 -04:00
if deltaData . action is ' text-diff '
2014-09-22 17:05:13 -04:00
return console . error " Couldn ' t show diff for left: #{ deltaData . left } , right: #{ deltaData . right } of delta: " , deltaData unless deltaData . left ? and deltaData . right ?
2014-04-12 00:11:52 -04:00
left = difflib . stringAsLines deltaData . left
right = difflib . stringAsLines deltaData . right
sm = new difflib . SequenceMatcher ( left , right )
opcodes = sm . get_opcodes ( )
el = deltaEl . find ( ' .text-diff ' )
options = { baseTextLines: left , newTextLines: right , opcodes: opcodes }
args = _ . defaults options , TEXTDIFF_OPTIONS
el . append ( diffview . buildView ( args ) )
2014-04-09 19:09:35 -04:00
2014-04-12 00:11:52 -04:00
getApplicableDelta: ->
delta = @ model . getDelta ( )
2014-05-30 16:40:38 -04:00
delta = deltasLib . pruneConflictsFromDelta delta , @ conflicts if @ conflicts
delta = deltasLib . pruneExpandedDeltasFromDelta delta , @ skippedDeltas if @ skippedDeltas
2014-07-04 10:43:23 -04:00
delta