Merge pull request #2537 from CatoTH/line-number-and-diff-caching

Caching results of insertLineNumbers and extractRangeByLineNumbers
This commit is contained in:
Emanuel Schütze 2016-11-01 23:41:29 +01:00 committed by GitHub
commit befb8083bf
2 changed files with 942 additions and 898 deletions

View File

@ -4,11 +4,16 @@
angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumbering']) angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumbering'])
.service('diffService', function (lineNumberingService) { .service('diffService', [
'lineNumberingService',
'$cacheFactory',
function (lineNumberingService, $cacheFactory) {
var ELEMENT_NODE = 1, var ELEMENT_NODE = 1,
TEXT_NODE = 3, TEXT_NODE = 3,
DOCUMENT_FRAGMENT_NODE = 11; DOCUMENT_FRAGMENT_NODE = 11;
var diffCache = $cacheFactory('diff.service');
this.TYPE_REPLACEMENT = 0; this.TYPE_REPLACEMENT = 0;
this.TYPE_INSERTION = 1; this.TYPE_INSERTION = 1;
this.TYPE_DELETION = 2; this.TYPE_DELETION = 2;
@ -322,6 +327,13 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
* *
*/ */
this.extractRangeByLineNumbers = function(fragment, fromLine, toLine, debug) { this.extractRangeByLineNumbers = function(fragment, fromLine, toLine, debug) {
var cacheKey = fromLine + "-" + toLine + "-" + lineNumberingService.djb2hash(fragment),
cached = diffCache.get(cacheKey);
if (!angular.isUndefined(cached)) {
return cached;
}
if (typeof(fragment) == 'string') { if (typeof(fragment) == 'string') {
fragment = this.htmlToFragment(fragment); fragment = this.htmlToFragment(fragment);
} }
@ -418,7 +430,7 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
currNode = currNode.parentNode; currNode = currNode.parentNode;
} }
return { var ret = {
'html': html, 'html': html,
'ancestor': ancestor, 'ancestor': ancestor,
'outerContextStart': outerContextStart, 'outerContextStart': outerContextStart,
@ -430,6 +442,9 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
'followingHtml': followingHtml, 'followingHtml': followingHtml,
'followingHtmlStartSnippet': followingHtmlStartSnippet 'followingHtmlStartSnippet': followingHtmlStartSnippet
}; };
diffCache.put(cacheKey, ret);
return ret;
}; };
/* /*
@ -627,7 +642,7 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
return this._serializeDom(mergedFragment, true); return this._serializeDom(mergedFragment, true);
}; };
}); }
]);
}()); }());

View File

@ -14,7 +14,9 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
* No constructs like <a...><div></div></a> are allowed. CSS-attributes like 'display: block' are ignored. * No constructs like <a...><div></div></a> are allowed. CSS-attributes like 'display: block' are ignored.
*/ */
.service('lineNumberingService', function () { .service('lineNumberingService', [
'$cacheFactory',
function ($cacheFactory) {
var ELEMENT_NODE = 1, var ELEMENT_NODE = 1,
TEXT_NODE = 3; TEXT_NODE = 3;
@ -22,6 +24,17 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
this._currentLineNumber = null; this._currentLineNumber = null;
this._prependLineNumberToFirstText = false; this._prependLineNumberToFirstText = false;
var lineNumberCache = $cacheFactory('linenumbering.service');
this.djb2hash = function(str) {
var hash = 5381, char;
for (var i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
hash = ((hash << 5) + hash) + char;
}
return hash.toString();
};
this._isInlineElement = function (node) { this._isInlineElement = function (node) {
var inlineElements = [ var inlineElements = [
'SPAN', 'A', 'EM', 'S', 'B', 'I', 'STRONG', 'U', 'BIG', 'SMALL', 'SUB', 'SUP', 'TT' 'SPAN', 'A', 'EM', 'S', 'B', 'I', 'STRONG', 'U', 'BIG', 'SMALL', 'SUB', 'SUP', 'TT'
@ -361,13 +374,28 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
}; };
this.insertLineNumbers = function (html, lineLength, highlight, callback, firstLine) { this.insertLineNumbers = function (html, lineLength, highlight, callback, firstLine) {
var newRoot = this.insertLineNumbersNode(html, lineLength, highlight, firstLine); var newHtml, newRoot;
if (highlight > 0) {
// Caching versions with highlighted line numbers is probably not worth it
newRoot = this.insertLineNumbersNode(html, lineLength, highlight, firstLine);
newHtml = newRoot.innerHTML;
} else {
var cacheKey = this.djb2hash(html);
newHtml = lineNumberCache.get(cacheKey);
if (angular.isUndefined(newHtml)) {
newRoot = this.insertLineNumbersNode(html, lineLength, highlight, firstLine);
newHtml = newRoot.innerHTML;
lineNumberCache.put(cacheKey, newHtml);
}
}
if (callback) { if (callback) {
callback(); callback();
} }
return newRoot.innerHTML; return newHtml;
}; };
this.stripLineNumbers = function (html) { this.stripLineNumbers = function (html) {
@ -376,7 +404,8 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
this._stripLineNumbers(root); this._stripLineNumbers(root);
return root.innerHTML; return root.innerHTML;
}; };
}); }
]);
}()); }());