-
-function FluidbookSearch() {
- this.indexLoaded = false;
+function FluidbookSearch(fluidbook) {
+ this.fluidbook = fluidbook;
+ this.indexLoaded = false;
+ this.termsToHighlight = [];
+ this.highlights = [];
+ this.init();
}
FluidbookSearch.prototype = {
- getHints: function(q, callback) {
- var $this = this;
- this._loadLib(function() {
- $this._getHints(q, callback);
- });
- },
- find: function(q, callback) {
- var $this = this;
- this._loadLib(function() {
- $this._find(q, callback);
- });
- },
- _loadLib: function(callback) {
- if (this.indexLoaded) {
- return callback();
- }
- var $this = this;
- loadJSLibrary('data/search.index.js', function() {
- loadJSLibrary('data/search.texts.js', function() {
- $this.indexLoaded = true;
- callback();
- });
- });
- },
- _getHints: function(q, callback) {
- var words = this.normalizeQuery(q);
- q = words.pop();
- var res = [];
- if (q.length < 3) {
- return res;
- }
+ init: function () {
+ var $this=this;
+ $(this.fluidbook).on('fluidbook.page.change.end', function (e, pageNr) {
+ $this.highlightSearchTerms(pageNr);
+ });
+ },
+ getHints: function (q, callback) {
+ var $this = this;
+ this._loadLib(function () {
+ $this._getHints(q, callback);
+ });
+ },
+ find: function (q, callback) {
+ var $this = this;
+ this._loadLib(function () {
+ $this._find(q, callback);
+ });
+ },
+ _loadLib: function (callback) {
+ if (this.indexLoaded) {
+ return callback();
+ }
+ var $this = this;
+ loadJSLibrary('data/search.index.js', function () {
+ loadJSLibrary('data/search.texts.js', function () {
+ loadJSLibrary('data/search.highlight.js', function () {
+ $this.indexLoaded = true;
+ callback();
+ });
+ });
+ });
+ },
+ _getHints: function (q, callback) {
+ var words = this.normalizeQuery(q);
+ q = words.pop();
+ var res = [];
+ if (q.length < 3) {
+ return res;
+ }
+
+ var v;
+ for (var k in INDEX) {
+ v = INDEX[k];
+ if (k.indexOf(q) != 0) {
+ continue;
+ }
+ res.push([k, v.t]);
+ }
+
+ res.sort(this.sortHints);
+ callback(res.slice(0, 12));
+ },
+ _find: function (q, callback) {
+ var words = this.normalizeQuery(q);
+ var res = {};
+ var terms = [];
+ var total = 0;
+ var q, v, k, kk, word, wordata, page, occurences;
+
+ for (kk in words) {
+ q = words[kk];
+ terms.push(q);
+ for (k in INDEX) {
+ v = INDEX[k];
+ if (k.indexOf(q) != 0) {
+ continue;
+ }
+
+ for (page in v.p) {
+ var occurences = v.p[page];
+ page = parseInt(page);
+ if (res[page] == undefined) {
+ res[page] = 0;
+ }
+ res[page] += occurences;
+ total += occurences;
+ }
+ }
+ }
+
+ callback({
+ total: total,
+ results: res,
+ terms: terms
+ });
+ },
+ sortHints: function (a, b) {
+ return b[1] - a[1];
+ },
+ kill: function () {
- var v;
- for (var k in INDEX) {
- v = INDEX[k];
- if (k.indexOf(q) != 0) {
- continue;
- }
- res.push([k, v.t]);
- }
+ },
+ normalizeQuery: function (q) {
+ q = this.noAccents(q);
+ q = q.toLowerCase();
+ return q.split(' ');
+ },
+ noAccents: function (source) {
+ source = source.replace(/[àáâãäå]/g, "a");
+ source = source.replace(/[ÀÁÂÃÄÅ]/g, "A");
+ source = source.replace(/[èéêë]/g, "e");
+ source = source.replace(/[ËÉÊÈ]/g, "E");
+ source = source.replace(/[ìíîï]/g, "i");
+ source = source.replace(/[ÌÍÎÏ]/g, "I");
+ source = source.replace(/[ðòóôõöø]/g, "o");
+ source = source.replace(/[ÐÒÓÔÕÖØ]/g, "O");
+ source = source.replace(/[ùúûü]/g, "u");
+ source = source.replace(/[ÙÚÛÜ]/g, "U");
+ source = source.replace(/[ýýÿ]/g, "y");
+ source = source.replace(/[ÝÝŸ]/g, "Y");
+ source = source.replace(/[ç]/g, "c");
+ source = source.replace(/[Ç]/g, "C");
+ source = source.replace(/[ñ]/g, "n");
+ source = source.replace(/[Ñ]/g, "N");
+ source = source.replace(/[š]/g, "s");
+ source = source.replace(/[Š]/g, "S");
+ source = source.replace(/[ž]/g, "z");
+ source = source.replace(/[Ž]/g, "Z");
+ source = source.replace(/[æ]/g, "ae");
+ source = source.replace(/[Æ]/g, "AE");
+ source = source.replace(/[œ]/g, "oe");
+ source = source.replace(/[Œ]/g, "OE");
+ return source;
+ },
+ setHighlightTerms: function (terms) {
+ this.termsToHighlight = terms;
+ this.highlights = [];
+ if (terms.length == 0) {
+ return;
+ }
+ for (var t in terms) {
+ var term = terms[t];
+ for (var w in HIGHLIGHTS) {
+ if (w.indexOf(term) == 0) {
+ var h = {occurences: HIGHLIGHTS[w], color: t, word: w, term: term};
+ this.highlights.push(h);
+ }
+ }
+ }
+ },
+ clearHighlights: function () {
+ $("#searchHighlights").html('');
+ },
+ highlightSearchTerms: function (pageNr) {
+ this.clearHighlights();
+ if (this.termsToHighlight.length == 0) {
+ return;
+ }
- res.sort(this.sortHints);
- callback(res.slice(0, 12));
- },
- _find: function(q, callback) {
- var words = this.normalizeQuery(q);
- var res = {};
- var terms = [];
- var total = 0;
- var q, v, k, kk, word, wordata, page, occurences;
- for (kk in words) {
- q = words[kk];
- for (k in INDEX) {
- v = INDEX[k];
- if (k.indexOf(q) != 0) {
- continue;
- }
- for (page in v.p) {
- var occurences = v.p[page];
- page = parseInt(page);
- if (res[page] == undefined) {
- res[page] = 0;
- }
- res[page] += occurences;
- total += occurences;
- }
- /*for (word in v.w) {
- wordata = v.w[word];
- terms.push(word);
- for (page in wordata.p) {
- occurences = wordata.p[page];
- page = parseInt(page);
- if (res[page] == undefined) {
- res[page] = 0;
- }
- res[page] += occurences;
- total += occurences;
- }
- }*/
- }
- }
+ var pageNrs = [];
+ if (this.fluidbook.resize.orientation == 'portrait') {
+ pageNrs.push(pageNr);
+ } else {
+ if (pageNr % 2 == 1) {
+ pageNr--;
+ }
+ pageNrs.push(pageNr);
+ pageNr++;
+ if (pageNr < this.fluidbook.datas.pages) {
+ pageNrs.push(pageNr);
+ }
+ }
- callback({
- total: total,
- results: res,
- terms: terms.join(' ')
- });
- },
- sortHints: function(a, b) {
- return b[1] - a[1];
- },
- kill: function() {
+ for (var i in this.highlights) {
+ var h = this.highlights[i];
+ for (var j in h.occurences) {
+ var o = h.occurences[j];
+ var pageIndex = pageNrs.indexOf(o.page);
+ if (pageIndex == -1) {
+ continue;
+ }
+ this.highlightOccurence(o, h.word, h.term, h.color, pageIndex * this.fluidbook.datas.width);
+ }
+ }
+ },
- },
- normalizeQuery: function(q) {
- q = this.noAccents(q);
- q = q.toLowerCase();
- return q.split(' ');
- },
- noAccents: function(source) {
- source = source.replace(/[àáâãäå]/g, "a");
- source = source.replace(/[ÀÁÂÃÄÅ]/g, "A");
- source = source.replace(/[èéêë]/g, "e");
- source = source.replace(/[ËÉÊÈ]/g, "E");
- source = source.replace(/[ìíîï]/g, "i");
- source = source.replace(/[ÌÍÎÏ]/g, "I");
- source = source.replace(/[ðòóôõöø]/g, "o");
- source = source.replace(/[ÐÒÓÔÕÖØ]/g, "O");
- source = source.replace(/[ùúûü]/g, "u");
- source = source.replace(/[ÙÚÛÜ]/g, "U");
- source = source.replace(/[ýýÿ]/g, "y");
- source = source.replace(/[ÝÝŸ]/g, "Y");
- source = source.replace(/[ç]/g, "c");
- source = source.replace(/[Ç]/g, "C");
- source = source.replace(/[ñ]/g, "n");
- source = source.replace(/[Ñ]/g, "N");
- source = source.replace(/[š]/g, "s");
- source = source.replace(/[Š]/g, "S");
- source = source.replace(/[ž]/g, "z");
- source = source.replace(/[Ž]/g, "Z");
- source = source.replace(/[æ]/g, "ae");
- source = source.replace(/[Æ]/g, "AE");
- source = source.replace(/[œ]/g, "oe");
- source = source.replace(/[Œ]/g, "OE");
- return source;
- }
+ highlightOccurence: function (position, word, term, color, offset) {
+ var padding = position.height * 0.2;
+ var z = this.fluidbook.datas.pageZoomFactor * 1.19;
+ var h = $('<div class="highlight" data-color="' + color + '"></div>');
+ $(h).css({top: (position.y - position.height - padding * 2) * z, left: (position.x - padding) * z + offset, width: (position.width + 2 * padding) * z, height: (position.height + padding * 3) * z});
+ $("#searchHighlights").append(h);
+ }
};