|
| 1 | + |
| 2 | +/// <reference path="../../references.js" /> |
| 3 | +(function () { |
| 4 | + "use strict"; |
| 5 | + |
| 6 | + var deltaDecorations = function (oldDecorations, newDecorations) { |
| 7 | + /// <summary> |
| 8 | + /// Update oldDecorations to match newDecorations. |
| 9 | + /// It will remove old decorations which are not found in new decorations |
| 10 | + /// and add only the really new decorations. |
| 11 | + /// </summary> |
| 12 | + /// <param name="oldDecorations" type="Array"> |
| 13 | + /// An array containing ids of existing decorations |
| 14 | + /// </param> |
| 15 | + /// <param name="newDecorations" type="Array"> |
| 16 | + /// An array containing literal objects describing new decorations. A |
| 17 | + /// literal contains the following two fields: |
| 18 | + /// range |
| 19 | + /// options |
| 20 | + /// </param> |
| 21 | + /// <returns type="Array"> |
| 22 | + /// Returns an array of decorations ids |
| 23 | + /// </returns> |
| 24 | + var hashFunc = function (range, options) { |
| 25 | + return range.startLineNumber + "," + range.startColumn + "-" + range.endLineNumber + "," + range.endColumn + |
| 26 | + "-" + options.hoverMessage + "-" + options.className + "-" + options.isOverlay + "-" + options.showInOverviewRuler; |
| 27 | + }; |
| 28 | + return this.changeDecorations(function (changeAccessor) { |
| 29 | + var i, len, oldDecorationsMap = {}, hash; |
| 30 | + |
| 31 | + // Record old decorations in a map |
| 32 | + // Two decorations can have the same hash |
| 33 | + for (i = 0, len = oldDecorations.length; i < len; i++) { |
| 34 | + hash = hashFunc(this.getDecorationRange(oldDecorations[i]), this.getDecorationOptions(oldDecorations[i])); |
| 35 | + oldDecorationsMap[hash] = oldDecorationsMap[hash] || []; |
| 36 | + oldDecorationsMap[hash].push(oldDecorations[i]); |
| 37 | + } |
| 38 | + |
| 39 | + // Add only new decorations & mark reused ones |
| 40 | + var j, lenJ, result = [], usedOldDecorations = {}, oldDecorationsCandidates, reusedOldDecoration; |
| 41 | + for (i = 0, len = newDecorations.length; i < len; i++) { |
| 42 | + hash = hashFunc(newDecorations[i].range, newDecorations[i].options); |
| 43 | + reusedOldDecoration = false; |
| 44 | + if (oldDecorationsMap.hasOwnProperty(hash)) { |
| 45 | + oldDecorationsCandidates = oldDecorationsMap[hash]; |
| 46 | + // We can try reusing an old decoration (if it hasn't been reused before) |
| 47 | + for (j = 0, lenJ = oldDecorationsCandidates.length; j < lenJ; j++) { |
| 48 | + if (!usedOldDecorations.hasOwnProperty(oldDecorationsCandidates[j])) { |
| 49 | + // Found an old decoration which can be reused & it hasn't been reused before |
| 50 | + reusedOldDecoration = true; |
| 51 | + usedOldDecorations[oldDecorationsCandidates[j]] = true; |
| 52 | + result.push(oldDecorationsCandidates[j]); |
| 53 | + break; |
| 54 | + } |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + if (!reusedOldDecoration) { |
| 59 | + result.push(changeAccessor.addDecoration(newDecorations[i].range, newDecorations[i].options)); |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | + // Remove unused old decorations |
| 64 | + for (i = 0, len = oldDecorations.length; i < len; i++) { |
| 65 | + if (!usedOldDecorations.hasOwnProperty(oldDecorations[i])) { |
| 66 | + changeAccessor.removeDecoration(oldDecorations[i]); |
| 67 | + } |
| 68 | + } |
| 69 | + |
| 70 | + return result; |
| 71 | + }.bind(this)); |
| 72 | + }; |
| 73 | + |
| 74 | +})(); |
0 commit comments