annotate .svn/pristine/79/7998baf8e95a22a5aa2950bf21a5c4bff46e87b8.svn-base @ 1524:82fac3dcf466 redmine-2.5-integration

Fix failure to interpret Javascript when autocompleting members for project
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Thu, 11 Sep 2014 10:24:38 +0100
parents 038ba2d95de8
children
rev   line source
Chris@1296 1 module RedmineDiff
Chris@1296 2 class Diff
Chris@1296 3
Chris@1296 4 VERSION = 0.3
Chris@1296 5
Chris@1296 6 def Diff.lcs(a, b)
Chris@1296 7 astart = 0
Chris@1296 8 bstart = 0
Chris@1296 9 afinish = a.length-1
Chris@1296 10 bfinish = b.length-1
Chris@1296 11 mvector = []
Chris@1296 12
Chris@1296 13 # First we prune off any common elements at the beginning
Chris@1296 14 while (astart <= afinish && bstart <= afinish && a[astart] == b[bstart])
Chris@1296 15 mvector[astart] = bstart
Chris@1296 16 astart += 1
Chris@1296 17 bstart += 1
Chris@1296 18 end
Chris@1296 19
Chris@1296 20 # now the end
Chris@1296 21 while (astart <= afinish && bstart <= bfinish && a[afinish] == b[bfinish])
Chris@1296 22 mvector[afinish] = bfinish
Chris@1296 23 afinish -= 1
Chris@1296 24 bfinish -= 1
Chris@1296 25 end
Chris@1296 26
Chris@1296 27 bmatches = b.reverse_hash(bstart..bfinish)
Chris@1296 28 thresh = []
Chris@1296 29 links = []
Chris@1296 30
Chris@1296 31 (astart..afinish).each { |aindex|
Chris@1296 32 aelem = a[aindex]
Chris@1296 33 next unless bmatches.has_key? aelem
Chris@1296 34 k = nil
Chris@1296 35 bmatches[aelem].reverse.each { |bindex|
Chris@1296 36 if k && (thresh[k] > bindex) && (thresh[k-1] < bindex)
Chris@1296 37 thresh[k] = bindex
Chris@1296 38 else
Chris@1296 39 k = thresh.replacenextlarger(bindex, k)
Chris@1296 40 end
Chris@1296 41 links[k] = [ (k==0) ? nil : links[k-1], aindex, bindex ] if k
Chris@1296 42 }
Chris@1296 43 }
Chris@1296 44
Chris@1296 45 if !thresh.empty?
Chris@1296 46 link = links[thresh.length-1]
Chris@1296 47 while link
Chris@1296 48 mvector[link[1]] = link[2]
Chris@1296 49 link = link[0]
Chris@1296 50 end
Chris@1296 51 end
Chris@1296 52
Chris@1296 53 return mvector
Chris@1296 54 end
Chris@1296 55
Chris@1296 56 def makediff(a, b)
Chris@1296 57 mvector = Diff.lcs(a, b)
Chris@1296 58 ai = bi = 0
Chris@1296 59 while ai < mvector.length
Chris@1296 60 bline = mvector[ai]
Chris@1296 61 if bline
Chris@1296 62 while bi < bline
Chris@1296 63 discardb(bi, b[bi])
Chris@1296 64 bi += 1
Chris@1296 65 end
Chris@1296 66 match(ai, bi)
Chris@1296 67 bi += 1
Chris@1296 68 else
Chris@1296 69 discarda(ai, a[ai])
Chris@1296 70 end
Chris@1296 71 ai += 1
Chris@1296 72 end
Chris@1296 73 while ai < a.length
Chris@1296 74 discarda(ai, a[ai])
Chris@1296 75 ai += 1
Chris@1296 76 end
Chris@1296 77 while bi < b.length
Chris@1296 78 discardb(bi, b[bi])
Chris@1296 79 bi += 1
Chris@1296 80 end
Chris@1296 81 match(ai, bi)
Chris@1296 82 1
Chris@1296 83 end
Chris@1296 84
Chris@1296 85 def compactdiffs
Chris@1296 86 diffs = []
Chris@1296 87 @diffs.each { |df|
Chris@1296 88 i = 0
Chris@1296 89 curdiff = []
Chris@1296 90 while i < df.length
Chris@1296 91 whot = df[i][0]
Chris@1296 92 s = @isstring ? df[i][2].chr : [df[i][2]]
Chris@1296 93 p = df[i][1]
Chris@1296 94 last = df[i][1]
Chris@1296 95 i += 1
Chris@1296 96 while df[i] && df[i][0] == whot && df[i][1] == last+1
Chris@1296 97 s << df[i][2]
Chris@1296 98 last = df[i][1]
Chris@1296 99 i += 1
Chris@1296 100 end
Chris@1296 101 curdiff.push [whot, p, s]
Chris@1296 102 end
Chris@1296 103 diffs.push curdiff
Chris@1296 104 }
Chris@1296 105 return diffs
Chris@1296 106 end
Chris@1296 107
Chris@1296 108 attr_reader :diffs, :difftype
Chris@1296 109
Chris@1296 110 def initialize(diffs_or_a, b = nil, isstring = nil)
Chris@1296 111 if b.nil?
Chris@1296 112 @diffs = diffs_or_a
Chris@1296 113 @isstring = isstring
Chris@1296 114 else
Chris@1296 115 @diffs = []
Chris@1296 116 @curdiffs = []
Chris@1296 117 makediff(diffs_or_a, b)
Chris@1296 118 @difftype = diffs_or_a.class
Chris@1296 119 end
Chris@1296 120 end
Chris@1296 121
Chris@1296 122 def match(ai, bi)
Chris@1296 123 @diffs.push @curdiffs unless @curdiffs.empty?
Chris@1296 124 @curdiffs = []
Chris@1296 125 end
Chris@1296 126
Chris@1296 127 def discarda(i, elem)
Chris@1296 128 @curdiffs.push ['-', i, elem]
Chris@1296 129 end
Chris@1296 130
Chris@1296 131 def discardb(i, elem)
Chris@1296 132 @curdiffs.push ['+', i, elem]
Chris@1296 133 end
Chris@1296 134
Chris@1296 135 def compact
Chris@1296 136 return Diff.new(compactdiffs)
Chris@1296 137 end
Chris@1296 138
Chris@1296 139 def compact!
Chris@1296 140 @diffs = compactdiffs
Chris@1296 141 end
Chris@1296 142
Chris@1296 143 def inspect
Chris@1296 144 @diffs.inspect
Chris@1296 145 end
Chris@1296 146
Chris@1296 147 end
Chris@1296 148 end
Chris@1296 149
Chris@1296 150 module Diffable
Chris@1296 151 def diff(b)
Chris@1296 152 RedmineDiff::Diff.new(self, b)
Chris@1296 153 end
Chris@1296 154
Chris@1296 155 # Create a hash that maps elements of the array to arrays of indices
Chris@1296 156 # where the elements are found.
Chris@1296 157
Chris@1296 158 def reverse_hash(range = (0...self.length))
Chris@1296 159 revmap = {}
Chris@1296 160 range.each { |i|
Chris@1296 161 elem = self[i]
Chris@1296 162 if revmap.has_key? elem
Chris@1296 163 revmap[elem].push i
Chris@1296 164 else
Chris@1296 165 revmap[elem] = [i]
Chris@1296 166 end
Chris@1296 167 }
Chris@1296 168 return revmap
Chris@1296 169 end
Chris@1296 170
Chris@1296 171 def replacenextlarger(value, high = nil)
Chris@1296 172 high ||= self.length
Chris@1296 173 if self.empty? || value > self[-1]
Chris@1296 174 push value
Chris@1296 175 return high
Chris@1296 176 end
Chris@1296 177 # binary search for replacement point
Chris@1296 178 low = 0
Chris@1296 179 while low < high
Chris@1296 180 index = (high+low)/2
Chris@1296 181 found = self[index]
Chris@1296 182 return nil if value == found
Chris@1296 183 if value > found
Chris@1296 184 low = index + 1
Chris@1296 185 else
Chris@1296 186 high = index
Chris@1296 187 end
Chris@1296 188 end
Chris@1296 189
Chris@1296 190 self[low] = value
Chris@1296 191 # $stderr << "replace #{value} : 0/#{low}/#{init_high} (#{steps} steps) (#{init_high-low} off )\n"
Chris@1296 192 # $stderr.puts self.inspect
Chris@1296 193 #gets
Chris@1296 194 #p length - low
Chris@1296 195 return low
Chris@1296 196 end
Chris@1296 197
Chris@1296 198 def patch(diff)
Chris@1296 199 newary = nil
Chris@1296 200 if diff.difftype == String
Chris@1296 201 newary = diff.difftype.new('')
Chris@1296 202 else
Chris@1296 203 newary = diff.difftype.new
Chris@1296 204 end
Chris@1296 205 ai = 0
Chris@1296 206 bi = 0
Chris@1296 207 diff.diffs.each { |d|
Chris@1296 208 d.each { |mod|
Chris@1296 209 case mod[0]
Chris@1296 210 when '-'
Chris@1296 211 while ai < mod[1]
Chris@1296 212 newary << self[ai]
Chris@1296 213 ai += 1
Chris@1296 214 bi += 1
Chris@1296 215 end
Chris@1296 216 ai += 1
Chris@1296 217 when '+'
Chris@1296 218 while bi < mod[1]
Chris@1296 219 newary << self[ai]
Chris@1296 220 ai += 1
Chris@1296 221 bi += 1
Chris@1296 222 end
Chris@1296 223 newary << mod[2]
Chris@1296 224 bi += 1
Chris@1296 225 else
Chris@1296 226 raise "Unknown diff action"
Chris@1296 227 end
Chris@1296 228 }
Chris@1296 229 }
Chris@1296 230 while ai < self.length
Chris@1296 231 newary << self[ai]
Chris@1296 232 ai += 1
Chris@1296 233 bi += 1
Chris@1296 234 end
Chris@1296 235 return newary
Chris@1296 236 end
Chris@1296 237 end
Chris@1296 238
Chris@1296 239 class Array
Chris@1296 240 include Diffable
Chris@1296 241 end
Chris@1296 242
Chris@1296 243 class String
Chris@1296 244 include Diffable
Chris@1296 245 end
Chris@1296 246
Chris@1296 247 =begin
Chris@1296 248 = Diff
Chris@1296 249 (({diff.rb})) - computes the differences between two arrays or
Chris@1296 250 strings. Copyright (C) 2001 Lars Christensen
Chris@1296 251
Chris@1296 252 == Synopsis
Chris@1296 253
Chris@1296 254 diff = Diff.new(a, b)
Chris@1296 255 b = a.patch(diff)
Chris@1296 256
Chris@1296 257 == Class Diff
Chris@1296 258 === Class Methods
Chris@1296 259 --- Diff.new(a, b)
Chris@1296 260 --- a.diff(b)
Chris@1296 261 Creates a Diff object which represent the differences between
Chris@1296 262 ((|a|)) and ((|b|)). ((|a|)) and ((|b|)) can be either be arrays
Chris@1296 263 of any objects, strings, or object of any class that include
Chris@1296 264 module ((|Diffable|))
Chris@1296 265
Chris@1296 266 == Module Diffable
Chris@1296 267 The module ((|Diffable|)) is intended to be included in any class for
Chris@1296 268 which differences are to be computed. Diffable is included into String
Chris@1296 269 and Array when (({diff.rb})) is (({require}))'d.
Chris@1296 270
Chris@1296 271 Classes including Diffable should implement (({[]})) to get element at
Chris@1296 272 integer indices, (({<<})) to append elements to the object and
Chris@1296 273 (({ClassName#new})) should accept 0 arguments to create a new empty
Chris@1296 274 object.
Chris@1296 275
Chris@1296 276 === Instance Methods
Chris@1296 277 --- Diffable#patch(diff)
Chris@1296 278 Applies the differences from ((|diff|)) to the object ((|obj|))
Chris@1296 279 and return the result. ((|obj|)) is not changed. ((|obj|)) and
Chris@1296 280 can be either an array or a string, but must match the object
Chris@1296 281 from which the ((|diff|)) was created.
Chris@1296 282 =end