@oat-sa/tao-core-ui 1.58.1 → 1.58.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actionbar.js +386 -395
- package/dist/adder.js +21 -19
- package/dist/animable/absorbable/absorbable.js +204 -213
- package/dist/animable/absorbable/css/absorb.css +1 -0
- package/dist/animable/absorbable/css/absorb.css.map +1 -1
- package/dist/animable/pulsable/pulsable.js +168 -177
- package/dist/autocomplete/css/autocomplete.css +1 -0
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/autocomplete.js +68 -66
- package/dist/badge/badge.js +188 -197
- package/dist/badge/css/badge.css +1 -0
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs.js +275 -284
- package/dist/btngrouper.js +5 -5
- package/dist/bulkActionPopup.js +490 -495
- package/dist/button.js +283 -291
- package/dist/cascadingComboBox.js +249 -258
- package/dist/ckeditor/ckConfigurator.js +26 -19
- package/dist/ckeditor/dtdHandler.js +11 -9
- package/dist/class/selector.js +441 -450
- package/dist/component/resizable.js +1 -1
- package/dist/component/windowed.js +285 -294
- package/dist/component.js +419 -428
- package/dist/contextualPopup.js +417 -426
- package/dist/dashboard.js +300 -309
- package/dist/datalist.js +753 -762
- package/dist/datatable/filterStrategy/multiple.js +1 -1
- package/dist/datatable/filterStrategy/single.js +1 -1
- package/dist/datatable.js +1527 -1550
- package/dist/dateRange/dateRange.js +393 -402
- package/dist/datetime/picker.js +665 -672
- package/dist/deleter.js +368 -377
- package/dist/destination/selector.js +286 -295
- package/dist/dialog/alert.js +3 -3
- package/dist/dialog/confirm.js +1 -1
- package/dist/dialog/confirmDelete.js +216 -225
- package/dist/dialog.js +650 -654
- package/dist/disabler.js +8 -8
- package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +166 -175
- package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +518 -527
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +380 -389
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +539 -548
- package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +369 -378
- package/dist/documentViewer/providers/pdfViewer.js +184 -193
- package/dist/documentViewer.js +292 -301
- package/dist/dropdown.js +383 -392
- package/dist/durationer.js +5 -5
- package/dist/dynamicComponent.js +597 -598
- package/dist/feedback.js +356 -362
- package/dist/figure/FigureStateActive.js +117 -108
- package/dist/filesender.js +2 -2
- package/dist/filter.js +230 -239
- package/dist/form/dropdownForm.js +355 -357
- package/dist/form/form.js +919 -690
- package/dist/form/simpleForm.js +1 -1
- package/dist/form/validator/renderer.js +233 -235
- package/dist/form/validator/validator.js +257 -189
- package/dist/form/widget/definitions.js +1 -1
- package/dist/form/widget/providers/checkBox.js +254 -259
- package/dist/form/widget/providers/comboBox.js +187 -192
- package/dist/form/widget/providers/default.js +8 -9
- package/dist/form/widget/providers/hidden.js +170 -179
- package/dist/form/widget/providers/hiddenBox.js +262 -267
- package/dist/form/widget/providers/radioBox.js +216 -225
- package/dist/form/widget/providers/textArea.js +187 -196
- package/dist/form/widget/providers/textBox.js +2 -3
- package/dist/form/widget/widget.js +473 -475
- package/dist/formValidator/formValidator.js +1 -1
- package/dist/formValidator/highlighters/message.js +1 -1
- package/dist/generis/form/form.js +314 -323
- package/dist/generis/validator/validator.js +209 -218
- package/dist/generis/widget/checkBox/checkBox.js +218 -227
- package/dist/generis/widget/comboBox/comboBox.js +179 -188
- package/dist/generis/widget/hiddenBox/hiddenBox.js +220 -229
- package/dist/generis/widget/textBox/textBox.js +169 -178
- package/dist/generis/widget/widget.js +246 -255
- package/dist/groupedComboBox.js +222 -231
- package/dist/groupvalidator.js +2 -2
- package/dist/highlighter.js +967 -958
- package/dist/image/ImgStateActive/helper.js +7 -5
- package/dist/image/ImgStateActive/initHelper.js +49 -43
- package/dist/image/ImgStateActive/initMediaEditor.js +24 -20
- package/dist/image/ImgStateActive/mediaSizer.js +14 -12
- package/dist/image/ImgStateActive.js +72 -70
- package/dist/incrementer.js +6 -6
- package/dist/inplacer.js +6 -6
- package/dist/itemButtonList/css/item-button-list.css +1 -0
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +439 -435
- package/dist/keyNavigation/navigableDomElement.js +51 -38
- package/dist/keyNavigation/navigator.js +85 -70
- package/dist/listbox.js +460 -469
- package/dist/liststyler.js +8 -8
- package/dist/loadingButton/loadingButton.js +209 -218
- package/dist/lock.js +476 -485
- package/dist/login/login.js +475 -484
- package/dist/maths/calculator/basicCalculator.js +235 -244
- package/dist/maths/calculator/calculatorComponent.js +3 -3
- package/dist/maths/calculator/core/board.js +772 -781
- package/dist/maths/calculator/core/expression.js +476 -485
- package/dist/maths/calculator/core/labels.js +228 -237
- package/dist/maths/calculator/core/tokenizer.js +1 -1
- package/dist/maths/calculator/core/tokens.js +163 -170
- package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +244 -253
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +279 -288
- package/dist/maths/calculator/scientificCalculator.js +327 -336
- package/dist/mediaEditor/mediaEditorComponent.js +238 -245
- package/dist/mediaEditor/plugins/mediaAlignment/helper.js +7 -7
- package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +229 -235
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +580 -589
- package/dist/mediaplayer/players/html5.js +666 -675
- package/dist/mediaplayer/players/youtube.js +419 -424
- package/dist/mediaplayer/support.js +11 -10
- package/dist/mediaplayer/utils/reminder.js +14 -13
- package/dist/mediaplayer/utils/timeObserver.js +10 -11
- package/dist/mediaplayer/youtubeManager.js +164 -145
- package/dist/mediaplayer.js +1565 -1520
- package/dist/mediasizer.js +669 -678
- package/dist/modal.js +10 -17
- package/dist/pageSizeSelector.js +219 -228
- package/dist/pagination/providers/pages.js +280 -289
- package/dist/pagination/providers/simple.js +192 -201
- package/dist/previewer.js +30 -30
- package/dist/progressbar.js +4 -4
- package/dist/report.js +347 -356
- package/dist/resource/filters.js +271 -280
- package/dist/resource/list.js +1264 -1273
- package/dist/resource/selector.js +865 -874
- package/dist/resource/tree.js +1483 -1492
- package/dist/resourcemgr/fileBrowser.js +564 -569
- package/dist/resourcemgr/filePreview.js +16 -16
- package/dist/resourcemgr/fileSelector.js +515 -524
- package/dist/resourcemgr/util/updatePermissions.js +2 -2
- package/dist/resourcemgr.js +306 -315
- package/dist/searchModal/advancedSearch.js +796 -767
- package/dist/searchModal.js +114 -91
- package/dist/switch/switch.js +298 -307
- package/dist/tabs.js +598 -575
- package/dist/taskQueue/status.js +312 -321
- package/dist/taskQueue/table.js +375 -384
- package/dist/taskQueue/taskQueueModel.js +488 -472
- package/dist/taskQueueButton/taskable.js +264 -273
- package/dist/taskQueueButton/treeButton.js +189 -198
- package/dist/themeLoader.js +24 -23
- package/dist/themes.js +1 -1
- package/dist/toggler.js +3 -3
- package/dist/tooltip.js +295 -304
- package/dist/transformer.js +2 -2
- package/dist/tristateCheckboxGroup.js +311 -320
- package/dist/uploader.js +687 -696
- package/dist/validator/Report.js +1 -1
- package/dist/validator/Validator.js +3 -3
- package/dist/validator/validators.js +9 -9
- package/dist/validator.js +240 -230
- package/dist/waitForMedia.js +1 -1
- package/package.json +3 -3
- package/src/animable/absorbable/css/absorb.css +1 -0
- package/src/animable/absorbable/css/absorb.css.map +1 -1
- package/src/autocomplete/css/autocomplete.css +1 -0
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/badge/css/badge.css +1 -0
- package/src/badge/css/badge.css.map +1 -1
- package/src/ckeditor/ckConfigurator.js +4 -0
- package/src/itemButtonList/css/item-button-list.css +1 -0
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/.DS_Store +0 -0
- package/src/css/basic.css +0 -7826
- package/src/css/basic.css.map +0 -1
- package/src/css/ckeditor/skins/tao/css/dialog.css +0 -950
- package/src/css/ckeditor/skins/tao/css/dialog.css.map +0 -1
- package/src/css/ckeditor/skins/tao/css/editor.css +0 -1850
- package/src/css/ckeditor/skins/tao/css/editor.css.map +0 -1
- package/src/scss/.DS_Store +0 -0
- package/src/scss/basic.scss +0 -16
- package/src/scss/ckeditor/skins/tao/scss/dialog.scss +0 -763
- package/src/scss/ckeditor/skins/tao/scss/editor.scss +0 -111
- package/src/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +0 -59
- package/src/scss/ckeditor/skins/tao/scss/inc/_colorpanel.scss +0 -118
- package/src/scss/ckeditor/skins/tao/scss/inc/_elementspath.scss +0 -69
- package/src/scss/ckeditor/skins/tao/scss/inc/_mainui.scss +0 -194
- package/src/scss/ckeditor/skins/tao/scss/inc/_menu.scss +0 -181
- package/src/scss/ckeditor/skins/tao/scss/inc/_panel.scss +0 -200
- package/src/scss/ckeditor/skins/tao/scss/inc/_presets.scss +0 -32
- package/src/scss/ckeditor/skins/tao/scss/inc/_reset.scss +0 -101
- package/src/scss/ckeditor/skins/tao/scss/inc/_richcombo.scss +0 -213
- package/src/scss/ckeditor/skins/tao/scss/inc/_tao.scss +0 -59
- package/src/scss/ckeditor/skins/tao/scss/inc/_toolbar.scss +0 -301
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff.b64 +0 -1
- package/src/scss/font/tao/tao.eot +0 -0
- package/src/scss/font/tao/tao.svg +0 -235
- package/src/scss/font/tao/tao.ttf +0 -0
- package/src/scss/font/tao/tao.woff +0 -0
- package/src/scss/inc/_base.scss +0 -496
- package/src/scss/inc/_bootstrap.scss +0 -6
- package/src/scss/inc/_buttons.scss +0 -114
- package/src/scss/inc/_colors.scss +0 -88
- package/src/scss/inc/_feedback.scss +0 -150
- package/src/scss/inc/_flex-grid.scss +0 -15
- package/src/scss/inc/_fonts.scss +0 -4
- package/src/scss/inc/_forms.scss +0 -827
- package/src/scss/inc/_functions.scss +0 -283
- package/src/scss/inc/_grid.scss +0 -66
- package/src/scss/inc/_jquery.nouislider.scss +0 -254
- package/src/scss/inc/_normalize.scss +0 -528
- package/src/scss/inc/_report.scss +0 -68
- package/src/scss/inc/_secondary-properties.scss +0 -89
- package/src/scss/inc/_select2.scss +0 -634
- package/src/scss/inc/_toolbars.scss +0 -155
- package/src/scss/inc/_tooltip.scss +0 -312
- package/src/scss/inc/_variables.scss +0 -21
- package/src/scss/inc/base/_highlight.scss +0 -5
- package/src/scss/inc/base/_list-style.scss +0 -59
- package/src/scss/inc/base/_svg.scss +0 -3
- package/src/scss/inc/base/_table.scss +0 -63
- package/src/scss/inc/fonts/_source-sans-pro.scss +0 -29
- package/src/scss/inc/fonts/_tao-icon-classes.scss +0 -226
- package/src/scss/inc/fonts/_tao-icon-def.scss +0 -12
- package/src/scss/inc/fonts/_tao-icon-vars.scss +0 -240
|
@@ -1,621 +1,612 @@
|
|
|
1
1
|
define(['lodash', 'handlebars', 'i18n', 'lib/dompurify/purify'], function (_, Handlebars, __, DOMPurify) { 'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
_ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
|
|
4
|
+
Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
|
|
5
|
+
__ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
|
|
6
|
+
DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
|
|
7
|
+
|
|
8
|
+
function _typeof(obj) {
|
|
9
|
+
"@babel/helpers - typeof";
|
|
10
|
+
|
|
11
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
|
|
12
|
+
return typeof obj;
|
|
13
|
+
} : function (obj) {
|
|
14
|
+
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
15
|
+
}, _typeof(obj);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function Helpers0 (hb) {
|
|
19
|
+
//register a i18n helper
|
|
20
|
+
hb.registerHelper('__', function (key) {
|
|
21
|
+
return __(key);
|
|
22
|
+
});
|
|
8
23
|
/**
|
|
9
|
-
*
|
|
10
|
-
* modify it under the terms of the GNU General Public License
|
|
11
|
-
* as published by the Free Software Foundation; under version 2
|
|
12
|
-
* of the License (non-upgradable).
|
|
13
|
-
*
|
|
14
|
-
* This program is distributed in the hope that it will be useful,
|
|
15
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
-
* GNU General Public License for more details.
|
|
18
|
-
*
|
|
19
|
-
* You should have received a copy of the GNU General Public License
|
|
20
|
-
* along with this program; if not, write to the Free Software
|
|
21
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
22
|
-
*
|
|
23
|
-
* Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
|
|
24
|
-
*
|
|
24
|
+
* Register dompurify helper
|
|
25
25
|
*
|
|
26
|
+
* https://github.com/cure53/DOMPurify
|
|
27
|
+
* with config SAFE_FOR_TEMPLATES: true
|
|
28
|
+
* to make output safe for template systems
|
|
26
29
|
*/
|
|
27
|
-
function Helpers0 (hb) {
|
|
28
|
-
//register a i18n helper
|
|
29
|
-
hb.registerHelper('__', function (key) {
|
|
30
|
-
return __(key);
|
|
31
|
-
});
|
|
32
|
-
/**
|
|
33
|
-
* Register dompurify helper
|
|
34
|
-
*
|
|
35
|
-
* https://github.com/cure53/DOMPurify
|
|
36
|
-
* with config SAFE_FOR_TEMPLATES: true
|
|
37
|
-
* to make output safe for template systems
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
hb.registerHelper('dompurify', function (context) {
|
|
41
|
-
return DOMPurify.sanitize(context);
|
|
42
|
-
});
|
|
43
|
-
/**
|
|
44
|
-
* Register join helper
|
|
45
|
-
*
|
|
46
|
-
* Example :
|
|
47
|
-
* var values = {a:v1, b:v2, c:v3};
|
|
48
|
-
* Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
|
|
49
|
-
* Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
|
|
50
|
-
*/
|
|
51
30
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
31
|
+
hb.registerHelper('dompurify', function (context) {
|
|
32
|
+
return DOMPurify.sanitize(context);
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Register join helper
|
|
36
|
+
*
|
|
37
|
+
* Example :
|
|
38
|
+
* var values = {a:v1, b:v2, c:v3};
|
|
39
|
+
* Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
|
|
40
|
+
* Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
|
|
41
|
+
*/
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
|
|
43
|
+
hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
|
|
44
|
+
var fragments = [];
|
|
45
|
+
keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
|
|
46
|
+
fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
|
|
47
|
+
wrapper = typeof wrapper === 'string' ? wrapper : '"';
|
|
60
48
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
value = value ? 'true' : 'false';
|
|
64
|
-
} else if (typeof value === 'object') {
|
|
65
|
-
value = _.values(value).join(' ');
|
|
66
|
-
}
|
|
67
|
-
} else {
|
|
68
|
-
value = '';
|
|
69
|
-
}
|
|
49
|
+
_.forIn(arr, function (value, key) {
|
|
50
|
+
var fragment = '';
|
|
70
51
|
|
|
71
|
-
|
|
72
|
-
|
|
52
|
+
if (value !== null || value !== undefined) {
|
|
53
|
+
if (typeof value === 'boolean') {
|
|
54
|
+
value = value ? 'true' : 'false';
|
|
55
|
+
} else if (_typeof(value) === 'object') {
|
|
56
|
+
value = _.values(value).join(' ');
|
|
73
57
|
}
|
|
74
|
-
|
|
75
|
-
fragment += wrapper + value + wrapper;
|
|
76
|
-
fragments.push(fragment);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
return fragments.join(fragmentGlue);
|
|
80
|
-
}); //register a classic "for loop" helper
|
|
81
|
-
//it also adds a local variable "i" as the index in each iteration loop
|
|
82
|
-
|
|
83
|
-
hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
|
|
84
|
-
var ret = '';
|
|
85
|
-
startIndex = parseInt(startIndex);
|
|
86
|
-
stopIndex = parseInt(stopIndex);
|
|
87
|
-
increment = parseInt(increment);
|
|
88
|
-
|
|
89
|
-
for (var i = startIndex; i < stopIndex; i += increment) {
|
|
90
|
-
ret += options.fn(_.extend({}, this, {
|
|
91
|
-
i: i
|
|
92
|
-
}));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return ret;
|
|
96
|
-
});
|
|
97
|
-
hb.registerHelper('equal', function (var1, var2, options) {
|
|
98
|
-
if (var1 == var2) {
|
|
99
|
-
return options.fn(this);
|
|
100
58
|
} else {
|
|
101
|
-
|
|
59
|
+
value = '';
|
|
102
60
|
}
|
|
103
|
-
}); // register a "get property" helper
|
|
104
|
-
// it gets the named property from the provided context
|
|
105
|
-
|
|
106
|
-
hb.registerHelper('property', function (name, context) {
|
|
107
|
-
return context[name] || '';
|
|
108
|
-
}); // register an 'includes' helper
|
|
109
|
-
// it checks if value is in array
|
|
110
61
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return options.fn(this);
|
|
62
|
+
if (keyValueGlue !== undefined) {
|
|
63
|
+
fragment += key + keyValueGlue;
|
|
114
64
|
}
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
65
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
Helpers0.__initialized = true;
|
|
121
|
-
}
|
|
122
|
-
var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
123
|
-
this.compilerInfo = [4,'>= 1.0.0'];
|
|
124
|
-
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
125
|
-
var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
buffer += "<span class=\"highlight ";
|
|
129
|
-
if (helper = helpers.cls) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
130
|
-
else { helper = (depth0 && depth0.cls); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
131
|
-
buffer += escapeExpression(stack1)
|
|
132
|
-
+ "\" data-match=\"";
|
|
133
|
-
if (helper = helpers.index) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
134
|
-
else { helper = (depth0 && depth0.index); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
135
|
-
buffer += escapeExpression(stack1)
|
|
136
|
-
+ "\">";
|
|
137
|
-
if (helper = helpers.text) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
138
|
-
else { helper = (depth0 && depth0.text); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
139
|
-
buffer += escapeExpression(stack1)
|
|
140
|
-
+ "</span>\n";
|
|
141
|
-
return buffer;
|
|
66
|
+
fragment += wrapper + value + wrapper;
|
|
67
|
+
fragments.push(fragment);
|
|
142
68
|
});
|
|
143
|
-
function matchTpl(data, options, asString) {
|
|
144
|
-
var html = Template(data, options);
|
|
145
|
-
return (asString || true) ? html : $(html);
|
|
146
|
-
}
|
|
147
69
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
* as published by the Free Software Foundation; under version 2
|
|
152
|
-
* of the License (non-upgradable).
|
|
153
|
-
*
|
|
154
|
-
* This program is distributed in the hope that it will be useful,
|
|
155
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
156
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
157
|
-
* GNU General Public License for more details.
|
|
158
|
-
*
|
|
159
|
-
* You should have received a copy of the GNU General Public License
|
|
160
|
-
* along with this program; if not, write to the Free Software
|
|
161
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
162
|
-
*
|
|
163
|
-
* Copyright (c) 2016 (original work) Open Assessment Technologies SA ;
|
|
164
|
-
*/
|
|
165
|
-
/**
|
|
166
|
-
* Map of special chars to normalize
|
|
167
|
-
* @type {Object}
|
|
168
|
-
*/
|
|
70
|
+
return fragments.join(fragmentGlue);
|
|
71
|
+
}); //register a classic "for loop" helper
|
|
72
|
+
//it also adds a local variable "i" as the index in each iteration loop
|
|
169
73
|
|
|
170
|
-
|
|
171
|
-
'
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
'\u201A': "'",
|
|
176
|
-
// Single low-9 quotation mark
|
|
177
|
-
'\u201B': "'",
|
|
178
|
-
// Single high-reversed-9 quotation mark
|
|
179
|
-
'\u201C': '"',
|
|
180
|
-
// Left double quotation mark
|
|
181
|
-
'\u201D': '"',
|
|
182
|
-
// Right double quotation mark
|
|
183
|
-
'\u201E': '"',
|
|
184
|
-
// Double low-9 quotation mark
|
|
185
|
-
'\u201F': '"',
|
|
186
|
-
// Double high-reversed-9 quotation mark
|
|
187
|
-
'\u00BC': '1/4',
|
|
188
|
-
// Vulgar fraction one quarter
|
|
189
|
-
'\u00BD': '1/2',
|
|
190
|
-
// Vulgar fraction one half
|
|
191
|
-
'\u00BE': '3/4' // Vulgar fraction three quarters
|
|
74
|
+
hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
|
|
75
|
+
var ret = '';
|
|
76
|
+
startIndex = parseInt(startIndex);
|
|
77
|
+
stopIndex = parseInt(stopIndex);
|
|
78
|
+
increment = parseInt(increment);
|
|
192
79
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
80
|
+
for (var i = startIndex; i < stopIndex; i += increment) {
|
|
81
|
+
ret += options.fn(_.extend({}, this, {
|
|
82
|
+
i: i
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
198
85
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
86
|
+
return ret;
|
|
87
|
+
});
|
|
88
|
+
hb.registerHelper('equal', function (var1, var2, options) {
|
|
89
|
+
if (var1 == var2) {
|
|
90
|
+
return options.fn(this);
|
|
91
|
+
} else {
|
|
92
|
+
return options.inverse(this);
|
|
93
|
+
}
|
|
94
|
+
}); // register a "get property" helper
|
|
95
|
+
// it gets the named property from the provided context
|
|
205
96
|
|
|
206
|
-
function
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Find terms in a text
|
|
213
|
-
* @param {String} query
|
|
214
|
-
* @param {String} text
|
|
215
|
-
* @returns {Array}
|
|
216
|
-
*/
|
|
97
|
+
hb.registerHelper('property', function (name, context) {
|
|
98
|
+
return context[name] || '';
|
|
99
|
+
}); // register an 'includes' helper
|
|
100
|
+
// it checks if value is in array
|
|
217
101
|
|
|
102
|
+
hb.registerHelper('includes', function (haystack, needle, options) {
|
|
103
|
+
if (_.contains(haystack, needle)) {
|
|
104
|
+
return options.fn(this);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!Helpers0.__initialized) {
|
|
110
|
+
Helpers0(Handlebars);
|
|
111
|
+
Helpers0.__initialized = true;
|
|
112
|
+
}
|
|
113
|
+
var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
114
|
+
this.compilerInfo = [4,'>= 1.0.0'];
|
|
115
|
+
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
116
|
+
var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
buffer += "<span class=\"highlight ";
|
|
120
|
+
if (helper = helpers.cls) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
121
|
+
else { helper = (depth0 && depth0.cls); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
122
|
+
buffer += escapeExpression(stack1)
|
|
123
|
+
+ "\" data-match=\"";
|
|
124
|
+
if (helper = helpers.index) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
125
|
+
else { helper = (depth0 && depth0.index); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
126
|
+
buffer += escapeExpression(stack1)
|
|
127
|
+
+ "\">";
|
|
128
|
+
if (helper = helpers.text) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
129
|
+
else { helper = (depth0 && depth0.text); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
130
|
+
buffer += escapeExpression(stack1)
|
|
131
|
+
+ "</span>\n";
|
|
132
|
+
return buffer;
|
|
133
|
+
});
|
|
134
|
+
function matchTpl(data, options, asString) {
|
|
135
|
+
var html = Template(data, options);
|
|
136
|
+
return (asString || true) ? html : $(html);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* This program is free software; you can redistribute it and/or
|
|
141
|
+
* modify it under the terms of the GNU General Public License
|
|
142
|
+
* as published by the Free Software Foundation; under version 2
|
|
143
|
+
* of the License (non-upgradable).
|
|
144
|
+
*
|
|
145
|
+
* This program is distributed in the hope that it will be useful,
|
|
146
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
147
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
148
|
+
* GNU General Public License for more details.
|
|
149
|
+
*
|
|
150
|
+
* You should have received a copy of the GNU General Public License
|
|
151
|
+
* along with this program; if not, write to the Free Software
|
|
152
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
153
|
+
*
|
|
154
|
+
* Copyright (c) 2016 (original work) Open Assessment Technologies SA ;
|
|
155
|
+
*/
|
|
156
|
+
/**
|
|
157
|
+
* Map of special chars to normalize
|
|
158
|
+
* @type {Object}
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
var charactersToNormalize = {
|
|
162
|
+
"\u2018": "'",
|
|
163
|
+
// Left single quotation mark
|
|
164
|
+
"\u2019": "'",
|
|
165
|
+
// Right single quotation mark
|
|
166
|
+
"\u201A": "'",
|
|
167
|
+
// Single low-9 quotation mark
|
|
168
|
+
"\u201B": "'",
|
|
169
|
+
// Single high-reversed-9 quotation mark
|
|
170
|
+
"\u201C": '"',
|
|
171
|
+
// Left double quotation mark
|
|
172
|
+
"\u201D": '"',
|
|
173
|
+
// Right double quotation mark
|
|
174
|
+
"\u201E": '"',
|
|
175
|
+
// Double low-9 quotation mark
|
|
176
|
+
"\u201F": '"',
|
|
177
|
+
// Double high-reversed-9 quotation mark
|
|
178
|
+
"\xBC": '1/4',
|
|
179
|
+
// Vulgar fraction one quarter
|
|
180
|
+
"\xBD": '1/2',
|
|
181
|
+
// Vulgar fraction one half
|
|
182
|
+
"\xBE": '3/4' // Vulgar fraction three quarters
|
|
183
|
+
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* RegExp that will match special chars to normalize
|
|
187
|
+
* @type {RegExp}
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
var normalizationRegex = new RegExp('[' + Object.keys(charactersToNormalize).join('') + ']', 'g');
|
|
191
|
+
/**
|
|
192
|
+
* Replaces special chars by normalized equivalent
|
|
193
|
+
* @param {String} text
|
|
194
|
+
* @returns {String}
|
|
195
|
+
*/
|
|
196
|
+
|
|
197
|
+
function normalizeSpecialChars(text) {
|
|
198
|
+
return text.replace(normalizationRegex, function (ch) {
|
|
199
|
+
return charactersToNormalize[ch];
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Find terms in a text
|
|
204
|
+
* @param {String} query
|
|
205
|
+
* @param {String} text
|
|
206
|
+
* @returns {Array}
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
function findInText(query, text) {
|
|
211
|
+
var queryLen = query.length;
|
|
212
|
+
var index,
|
|
213
|
+
end = 0;
|
|
214
|
+
var matches = [];
|
|
215
|
+
|
|
216
|
+
if (queryLen) {
|
|
217
|
+
do {
|
|
218
|
+
index = text.indexOf(query, end);
|
|
219
|
+
end = index + queryLen;
|
|
220
|
+
|
|
221
|
+
if (index !== -1) {
|
|
222
|
+
matches.push([index, end]);
|
|
223
|
+
}
|
|
224
|
+
} while (index !== -1);
|
|
225
|
+
}
|
|
218
226
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
227
|
+
return matches;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Find the query in the whole document
|
|
231
|
+
* @param {String} query
|
|
232
|
+
* @param {Array} contentText
|
|
233
|
+
* @param {Object} config
|
|
234
|
+
* @returns {Array}
|
|
235
|
+
*/
|
|
224
236
|
|
|
225
|
-
if (queryLen) {
|
|
226
|
-
do {
|
|
227
|
-
index = text.indexOf(query, end);
|
|
228
|
-
end = index + queryLen;
|
|
229
237
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
} while (index !== -1);
|
|
234
|
-
}
|
|
238
|
+
function findInDocument(query, contentText, config) {
|
|
239
|
+
var normalizedQuery = normalizeSpecialChars(query);
|
|
235
240
|
|
|
236
|
-
|
|
241
|
+
if (!config.caseSensitive) {
|
|
242
|
+
normalizedQuery = normalizedQuery.toLowerCase();
|
|
237
243
|
}
|
|
238
|
-
/**
|
|
239
|
-
* Find the query in the whole document
|
|
240
|
-
* @param {String} query
|
|
241
|
-
* @param {Array} contentText
|
|
242
|
-
* @param {Object} config
|
|
243
|
-
* @returns {Array}
|
|
244
|
-
*/
|
|
245
|
-
|
|
246
244
|
|
|
247
|
-
|
|
248
|
-
var
|
|
245
|
+
return _.times(contentText.length, function (pageIndex) {
|
|
246
|
+
var pageContent = normalizeSpecialChars(contentText[pageIndex]);
|
|
249
247
|
|
|
250
248
|
if (!config.caseSensitive) {
|
|
251
|
-
|
|
249
|
+
pageContent = pageContent.toLowerCase();
|
|
252
250
|
}
|
|
253
251
|
|
|
254
|
-
return
|
|
255
|
-
|
|
252
|
+
return findInText(normalizedQuery, pageContent);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Wraps a text into a highlighting span
|
|
257
|
+
* @param {String} text - The text to highlight
|
|
258
|
+
* @param {Number} index - The match index
|
|
259
|
+
* @param {String} [cls] - An additional CSS class to set
|
|
260
|
+
* @returns {String}
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
function highlight(text, index, cls) {
|
|
265
|
+
return matchTpl({
|
|
266
|
+
text: text,
|
|
267
|
+
index: index,
|
|
268
|
+
cls: cls
|
|
269
|
+
}).trim();
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Highlights a substring in a text
|
|
273
|
+
* @param {String} text - The text in which highlight the substring
|
|
274
|
+
* @param {Number} start - The start position of the substring in the text
|
|
275
|
+
* @param {Number} end - The end position of the substring in the text
|
|
276
|
+
* @param {Number} index - The match index
|
|
277
|
+
* @param {String} [cls] - An additional CSS class to set
|
|
278
|
+
* @returns {String}
|
|
279
|
+
*/
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
function highlightInText(text, start, end, index, cls) {
|
|
283
|
+
return text.substring(0, start) + highlight(text.substring(start, end), index, cls) + text.substring(end);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Refines the array of matches to provide positions inside the text layer per nodes basis
|
|
287
|
+
* @param {Array} matches
|
|
288
|
+
* @param {Object} pageContent
|
|
289
|
+
* @returns {Array}
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
function refineMatches(matches, pageContent) {
|
|
294
|
+
var refinedMatches = [];
|
|
295
|
+
var textItems = pageContent.content.items;
|
|
296
|
+
var count = textItems.length;
|
|
297
|
+
var cursor = 0;
|
|
298
|
+
var strPos = 0;
|
|
299
|
+
|
|
300
|
+
_.forEach(matches, function (match, index) {
|
|
301
|
+
var matchStart = match[0];
|
|
302
|
+
var matchEnd = match[1];
|
|
303
|
+
var position = {
|
|
304
|
+
index: index
|
|
305
|
+
};
|
|
256
306
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
307
|
+
while (cursor < count && matchStart >= strPos + textItems[cursor].str.length) {
|
|
308
|
+
strPos += textItems[cursor].str.length;
|
|
309
|
+
cursor++;
|
|
310
|
+
}
|
|
260
311
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
* Wraps a text into a highlighting span
|
|
266
|
-
* @param {String} text - The text to highlight
|
|
267
|
-
* @param {Number} index - The match index
|
|
268
|
-
* @param {String} [cls] - An additional CSS class to set
|
|
269
|
-
* @returns {String}
|
|
270
|
-
*/
|
|
312
|
+
position.begin = {
|
|
313
|
+
node: cursor,
|
|
314
|
+
offset: matchStart - strPos
|
|
315
|
+
};
|
|
271
316
|
|
|
317
|
+
while (cursor < count && matchEnd > strPos + textItems[cursor].str.length) {
|
|
318
|
+
strPos += textItems[cursor].str.length;
|
|
319
|
+
cursor++;
|
|
320
|
+
}
|
|
272
321
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
322
|
+
position.end = {
|
|
323
|
+
node: cursor,
|
|
324
|
+
offset: matchEnd - strPos
|
|
325
|
+
};
|
|
326
|
+
refinedMatches.push(position);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
return refinedMatches;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Renders the matches into the text layer
|
|
333
|
+
* @param {Array} matches
|
|
334
|
+
* @param {Object} pageContent
|
|
335
|
+
* @param {Number} [selectedMatch]
|
|
336
|
+
*/
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
function renderMatches(matches, pageContent, selectedMatch) {
|
|
340
|
+
var positions = refineMatches(matches, pageContent);
|
|
341
|
+
var matchIndex = positions.length - 1;
|
|
342
|
+
var nodes = pageContent.nodes;
|
|
343
|
+
var selected = matchIndex === selectedMatch;
|
|
344
|
+
|
|
345
|
+
_.forEachRight(nodes, function (node, nodeIndex) {
|
|
346
|
+
var nodeText = pageContent.content.items[nodeIndex].str;
|
|
347
|
+
var match, startInNode, endInNode, nodeInMatch, cls;
|
|
348
|
+
|
|
349
|
+
while (matchIndex >= 0) {
|
|
350
|
+
match = positions[matchIndex];
|
|
351
|
+
startInNode = match.begin.node === nodeIndex;
|
|
352
|
+
endInNode = match.end.node === nodeIndex;
|
|
353
|
+
nodeInMatch = nodeIndex > match.begin.node && nodeIndex < match.end.node;
|
|
354
|
+
cls = selected ? ' selected' : '';
|
|
355
|
+
|
|
356
|
+
if (startInNode && endInNode) {
|
|
357
|
+
nodeText = highlightInText(nodeText, match.begin.offset, match.end.offset, match.index, cls);
|
|
358
|
+
matchIndex--;
|
|
359
|
+
} else if (startInNode) {
|
|
360
|
+
nodeText = highlightInText(nodeText, match.begin.offset, nodeText.length, match.index, 'begin' + cls);
|
|
361
|
+
matchIndex--;
|
|
362
|
+
} else if (endInNode) {
|
|
363
|
+
nodeText = highlightInText(nodeText, 0, match.end.offset, match.index, 'end' + cls);
|
|
364
|
+
break;
|
|
365
|
+
} else if (nodeInMatch) {
|
|
366
|
+
nodeText = highlight(nodeText, match.index, 'middle' + cls);
|
|
367
|
+
break;
|
|
368
|
+
} else {
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
289
371
|
|
|
372
|
+
selected = matchIndex === selectedMatch;
|
|
373
|
+
}
|
|
290
374
|
|
|
291
|
-
|
|
292
|
-
|
|
375
|
+
node.innerHTML = nodeText;
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Embeds the search engine for the PDF viewer
|
|
380
|
+
* @param {Object} config A config set
|
|
381
|
+
* @param {Object} config.textManager - The textManager component that gives access to the text content
|
|
382
|
+
* @param {Boolean} [config.caseSensitive] - Use a case sensitive search when the search feature is available
|
|
383
|
+
* @returns {Object} Returns the search engine instance
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
function pdfjsSearchFactory(config) {
|
|
388
|
+
var textManager = null;
|
|
389
|
+
var currentQuery = null;
|
|
390
|
+
var currentMatch = null;
|
|
391
|
+
var matches = [];
|
|
392
|
+
var pages = [];
|
|
393
|
+
var count = 0;
|
|
394
|
+
config = config || {};
|
|
395
|
+
textManager = config.textManager;
|
|
396
|
+
|
|
397
|
+
if (!_.isPlainObject(textManager)) {
|
|
398
|
+
throw new TypeError('You must provide a textManager to give access to the PDF text content! [config.textManager is missing]');
|
|
293
399
|
}
|
|
294
|
-
/**
|
|
295
|
-
* Refines the array of matches to provide positions inside the text layer per nodes basis
|
|
296
|
-
* @param {Array} matches
|
|
297
|
-
* @param {Object} pageContent
|
|
298
|
-
* @returns {Array}
|
|
299
|
-
*/
|
|
300
400
|
|
|
401
|
+
return {
|
|
402
|
+
/**
|
|
403
|
+
* Gets the list of page numbers that lead to search matches
|
|
404
|
+
* @returns {Array}
|
|
405
|
+
*/
|
|
406
|
+
getPages: function getPages() {
|
|
407
|
+
return pages;
|
|
408
|
+
},
|
|
301
409
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
410
|
+
/**
|
|
411
|
+
* Gets the search matches
|
|
412
|
+
* @returns {Array}
|
|
413
|
+
*/
|
|
414
|
+
getMatches: function getMatches() {
|
|
415
|
+
return matches;
|
|
416
|
+
},
|
|
308
417
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
418
|
+
/**
|
|
419
|
+
* Gets the number of search matches
|
|
420
|
+
* @returns {Number}
|
|
421
|
+
*/
|
|
422
|
+
getMatchCount: function getMatchCount() {
|
|
423
|
+
return count;
|
|
424
|
+
},
|
|
315
425
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
426
|
+
/**
|
|
427
|
+
* Clears the search matches
|
|
428
|
+
*/
|
|
429
|
+
clearMatches: function clearMatches() {
|
|
430
|
+
currentMatch = null;
|
|
431
|
+
matches = [];
|
|
432
|
+
pages = [];
|
|
433
|
+
count = 0;
|
|
434
|
+
},
|
|
320
435
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
436
|
+
/**
|
|
437
|
+
* Sets the text manager
|
|
438
|
+
* @param {Object} manager
|
|
439
|
+
*/
|
|
440
|
+
setTextManager: function setTextManager(manager) {
|
|
441
|
+
textManager = manager;
|
|
442
|
+
},
|
|
325
443
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
444
|
+
/**
|
|
445
|
+
* Gets the text manager
|
|
446
|
+
* @returns {Object}
|
|
447
|
+
*/
|
|
448
|
+
getTextManager: function getTextManager() {
|
|
449
|
+
return textManager;
|
|
450
|
+
},
|
|
330
451
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
452
|
+
/**
|
|
453
|
+
* Gets the currently matched query
|
|
454
|
+
* @returns {String}
|
|
455
|
+
*/
|
|
456
|
+
getQuery: function getQuery() {
|
|
457
|
+
return currentQuery;
|
|
458
|
+
},
|
|
337
459
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
460
|
+
/**
|
|
461
|
+
* Gets the current match data. It contains:
|
|
462
|
+
* - overall: the index of the match over all the document, starting at 1
|
|
463
|
+
* - page: the page number of the match, starting at 1
|
|
464
|
+
* - index: the index of the match within its page, starting at 0
|
|
465
|
+
* @returns {Object}
|
|
466
|
+
*/
|
|
467
|
+
getCurrentMatch: function getCurrentMatch() {
|
|
468
|
+
return currentMatch;
|
|
469
|
+
},
|
|
346
470
|
|
|
471
|
+
/**
|
|
472
|
+
* Go to the previous match and returns the match data
|
|
473
|
+
* @returns {Boolean} Returns true if the search has reached the beginning of the document and moved to the end.
|
|
474
|
+
*/
|
|
475
|
+
previousMatch: function previousMatch() {
|
|
476
|
+
var pageIndex;
|
|
477
|
+
var loop = false;
|
|
347
478
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
var nodes = pageContent.nodes;
|
|
352
|
-
var selected = matchIndex === selectedMatch;
|
|
353
|
-
|
|
354
|
-
_.forEachRight(nodes, function (node, nodeIndex) {
|
|
355
|
-
var nodeText = pageContent.content.items[nodeIndex].str;
|
|
356
|
-
var match, startInNode, endInNode, nodeInMatch, cls;
|
|
357
|
-
|
|
358
|
-
while (matchIndex >= 0) {
|
|
359
|
-
match = positions[matchIndex];
|
|
360
|
-
startInNode = match.begin.node === nodeIndex;
|
|
361
|
-
endInNode = match.end.node === nodeIndex;
|
|
362
|
-
nodeInMatch = nodeIndex > match.begin.node && nodeIndex < match.end.node;
|
|
363
|
-
cls = selected ? ' selected' : '';
|
|
364
|
-
|
|
365
|
-
if (startInNode && endInNode) {
|
|
366
|
-
nodeText = highlightInText(nodeText, match.begin.offset, match.end.offset, match.index, cls);
|
|
367
|
-
matchIndex--;
|
|
368
|
-
} else if (startInNode) {
|
|
369
|
-
nodeText = highlightInText(nodeText, match.begin.offset, nodeText.length, match.index, 'begin' + cls);
|
|
370
|
-
matchIndex--;
|
|
371
|
-
} else if (endInNode) {
|
|
372
|
-
nodeText = highlightInText(nodeText, 0, match.end.offset, match.index, 'end' + cls);
|
|
373
|
-
break;
|
|
374
|
-
} else if (nodeInMatch) {
|
|
375
|
-
nodeText = highlight(nodeText, match.index, 'middle' + cls);
|
|
376
|
-
break;
|
|
479
|
+
if (currentMatch) {
|
|
480
|
+
if (currentMatch.index) {
|
|
481
|
+
currentMatch.index--;
|
|
377
482
|
} else {
|
|
378
|
-
|
|
379
|
-
|
|
483
|
+
pageIndex = _.indexOf(pages, currentMatch.page);
|
|
484
|
+
loop = !pageIndex;
|
|
485
|
+
currentMatch.page = pages[(pageIndex + pages.length - 1) % pages.length];
|
|
486
|
+
currentMatch.index = matches[currentMatch.page - 1].length - 1;
|
|
487
|
+
} // the overall index start at 1 instead of 0, so the formula is a little bit more complex
|
|
488
|
+
|
|
380
489
|
|
|
381
|
-
|
|
490
|
+
currentMatch.overall = (currentMatch.overall + count - 2) % count + 1;
|
|
382
491
|
}
|
|
383
492
|
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
493
|
+
return loop;
|
|
494
|
+
},
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Go to the next match and returns the match data
|
|
498
|
+
* @returns {Boolean} Returns true if the search has reached the end of the document and moved to the beginning.
|
|
499
|
+
*/
|
|
500
|
+
nextMatch: function nextMatch() {
|
|
501
|
+
var pageIndex;
|
|
502
|
+
var loop = false;
|
|
394
503
|
|
|
504
|
+
if (currentMatch) {
|
|
505
|
+
if (currentMatch.index + 1 < matches[currentMatch.page - 1].length) {
|
|
506
|
+
currentMatch.index++;
|
|
507
|
+
} else {
|
|
508
|
+
pageIndex = _.indexOf(pages, currentMatch.page);
|
|
509
|
+
loop = pageIndex === pages.length - 1;
|
|
510
|
+
currentMatch.page = pages[(pageIndex + 1) % pages.length];
|
|
511
|
+
currentMatch.index = 0;
|
|
512
|
+
} // the overall index start at 1 instead of 0, so the formula is a little bit more complex
|
|
395
513
|
|
|
396
|
-
function pdfjsSearchFactory(config) {
|
|
397
|
-
var textManager = null;
|
|
398
|
-
var currentQuery = null;
|
|
399
|
-
var currentMatch = null;
|
|
400
|
-
var matches = [];
|
|
401
|
-
var pages = [];
|
|
402
|
-
var count = 0;
|
|
403
|
-
config = config || {};
|
|
404
|
-
textManager = config.textManager;
|
|
405
514
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
515
|
+
currentMatch.overall = currentMatch.overall % count + 1;
|
|
516
|
+
}
|
|
409
517
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
* @returns {Number}
|
|
430
|
-
*/
|
|
431
|
-
getMatchCount: function getMatchCount() {
|
|
432
|
-
return count;
|
|
433
|
-
},
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Clears the search matches
|
|
437
|
-
*/
|
|
438
|
-
clearMatches: function clearMatches() {
|
|
518
|
+
return loop;
|
|
519
|
+
},
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Searches for the requested query.
|
|
523
|
+
* The promise will return the page number of the first match, that could be 0 if no result has been found.
|
|
524
|
+
* @param {String} query - The terms to search for
|
|
525
|
+
* @param {Number} [pageNum] - An optional page number from which start the search
|
|
526
|
+
* @returns {Promise}
|
|
527
|
+
*/
|
|
528
|
+
search: function search(query, pageNum) {
|
|
529
|
+
matches = null;
|
|
530
|
+
return textManager.getContents().then(function (pageContents) {
|
|
531
|
+
var contentText = _.map(pageContents, 'text');
|
|
532
|
+
|
|
533
|
+
var firstPage = 0;
|
|
534
|
+
var firstMatch = 0;
|
|
535
|
+
matches = findInDocument(query, contentText, config);
|
|
536
|
+
currentQuery = query;
|
|
439
537
|
currentMatch = null;
|
|
440
|
-
matches = [];
|
|
441
538
|
pages = [];
|
|
442
539
|
count = 0;
|
|
443
|
-
},
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Sets the text manager
|
|
447
|
-
* @param {Object} manager
|
|
448
|
-
*/
|
|
449
|
-
setTextManager: function setTextManager(manager) {
|
|
450
|
-
textManager = manager;
|
|
451
|
-
},
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
* Gets the text manager
|
|
455
|
-
* @returns {Object}
|
|
456
|
-
*/
|
|
457
|
-
getTextManager: function getTextManager() {
|
|
458
|
-
return textManager;
|
|
459
|
-
},
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Gets the currently matched query
|
|
463
|
-
* @returns {String}
|
|
464
|
-
*/
|
|
465
|
-
getQuery: function getQuery() {
|
|
466
|
-
return currentQuery;
|
|
467
|
-
},
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Gets the current match data. It contains:
|
|
471
|
-
* - overall: the index of the match over all the document, starting at 1
|
|
472
|
-
* - page: the page number of the match, starting at 1
|
|
473
|
-
* - index: the index of the match within its page, starting at 0
|
|
474
|
-
* @returns {Object}
|
|
475
|
-
*/
|
|
476
|
-
getCurrentMatch: function getCurrentMatch() {
|
|
477
|
-
return currentMatch;
|
|
478
|
-
},
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Go to the previous match and returns the match data
|
|
482
|
-
* @returns {Boolean} Returns true if the search has reached the beginning of the document and moved to the end.
|
|
483
|
-
*/
|
|
484
|
-
previousMatch: function previousMatch() {
|
|
485
|
-
var pageIndex;
|
|
486
|
-
var loop = false;
|
|
487
|
-
|
|
488
|
-
if (currentMatch) {
|
|
489
|
-
if (currentMatch.index) {
|
|
490
|
-
currentMatch.index--;
|
|
491
|
-
} else {
|
|
492
|
-
pageIndex = _.indexOf(pages, currentMatch.page);
|
|
493
|
-
loop = !pageIndex;
|
|
494
|
-
currentMatch.page = pages[(pageIndex + pages.length - 1) % pages.length];
|
|
495
|
-
currentMatch.index = matches[currentMatch.page - 1].length - 1;
|
|
496
|
-
} // the overall index start at 1 instead of 0, so the formula is a little bit more complex
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
currentMatch.overall = (currentMatch.overall + count - 2) % count + 1;
|
|
500
|
-
}
|
|
501
540
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
* @returns {Boolean} Returns true if the search has reached the end of the document and moved to the beginning.
|
|
508
|
-
*/
|
|
509
|
-
nextMatch: function nextMatch() {
|
|
510
|
-
var pageIndex;
|
|
511
|
-
var loop = false;
|
|
512
|
-
|
|
513
|
-
if (currentMatch) {
|
|
514
|
-
if (currentMatch.index + 1 < matches[currentMatch.page - 1].length) {
|
|
515
|
-
currentMatch.index++;
|
|
516
|
-
} else {
|
|
517
|
-
pageIndex = _.indexOf(pages, currentMatch.page);
|
|
518
|
-
loop = pageIndex === pages.length - 1;
|
|
519
|
-
currentMatch.page = pages[(pageIndex + 1) % pages.length];
|
|
520
|
-
currentMatch.index = 0;
|
|
521
|
-
} // the overall index start at 1 instead of 0, so the formula is a little bit more complex
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
currentMatch.overall = currentMatch.overall % count + 1;
|
|
525
|
-
}
|
|
541
|
+
_.forEach(matches, function (pageMatches, pageIndex) {
|
|
542
|
+
var page = pageIndex + 1;
|
|
543
|
+
|
|
544
|
+
if (pageMatches.length > 0) {
|
|
545
|
+
pages.push(page);
|
|
526
546
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
/**
|
|
531
|
-
* Searches for the requested query.
|
|
532
|
-
* The promise will return the page number of the first match, that could be 0 if no result has been found.
|
|
533
|
-
* @param {String} query - The terms to search for
|
|
534
|
-
* @param {Number} [pageNum] - An optional page number from which start the search
|
|
535
|
-
* @returns {Promise}
|
|
536
|
-
*/
|
|
537
|
-
search: function search(query, pageNum) {
|
|
538
|
-
matches = null;
|
|
539
|
-
return textManager.getContents().then(function (pageContents) {
|
|
540
|
-
var contentText = _.map(pageContents, 'text');
|
|
541
|
-
|
|
542
|
-
var firstPage = 0;
|
|
543
|
-
var firstMatch = 0;
|
|
544
|
-
matches = findInDocument(query, contentText, config);
|
|
545
|
-
currentQuery = query;
|
|
546
|
-
currentMatch = null;
|
|
547
|
-
pages = [];
|
|
548
|
-
count = 0;
|
|
549
|
-
|
|
550
|
-
_.forEach(matches, function (pageMatches, pageIndex) {
|
|
551
|
-
var page = pageIndex + 1;
|
|
552
|
-
|
|
553
|
-
if (pageMatches.length > 0) {
|
|
554
|
-
pages.push(page);
|
|
555
|
-
|
|
556
|
-
if (!firstPage && page >= pageNum) {
|
|
557
|
-
firstPage = page;
|
|
558
|
-
firstMatch = count;
|
|
559
|
-
}
|
|
547
|
+
if (!firstPage && page >= pageNum) {
|
|
548
|
+
firstPage = page;
|
|
549
|
+
firstMatch = count;
|
|
560
550
|
}
|
|
551
|
+
}
|
|
561
552
|
|
|
562
|
-
|
|
563
|
-
|
|
553
|
+
count += pageMatches.length;
|
|
554
|
+
});
|
|
564
555
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
556
|
+
if (!firstPage) {
|
|
557
|
+
firstPage = pages[0] || 0;
|
|
558
|
+
}
|
|
568
559
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
560
|
+
if (firstPage) {
|
|
561
|
+
currentMatch = {
|
|
562
|
+
overall: firstMatch + 1,
|
|
563
|
+
// the overall index of the match
|
|
564
|
+
page: firstPage,
|
|
565
|
+
// the page number of the match
|
|
566
|
+
index: 0 // the index of the match within its page
|
|
576
567
|
|
|
577
|
-
|
|
578
|
-
|
|
568
|
+
};
|
|
569
|
+
}
|
|
579
570
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Displays the search matches on the rendered page
|
|
586
|
-
* @param {Number} pageNum - The page number of the rendered page
|
|
587
|
-
* @returns {Promise}
|
|
588
|
-
*/
|
|
589
|
-
updateMatches: function updateMatches(pageNum) {
|
|
590
|
-
return textManager.getPageContent(pageNum).then(function (pageContent) {
|
|
591
|
-
var selectedMatch;
|
|
592
|
-
|
|
593
|
-
if (currentMatch && currentMatch.page === pageNum) {
|
|
594
|
-
selectedMatch = currentMatch.index;
|
|
595
|
-
}
|
|
571
|
+
return firstPage;
|
|
572
|
+
});
|
|
573
|
+
},
|
|
596
574
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
575
|
+
/**
|
|
576
|
+
* Displays the search matches on the rendered page
|
|
577
|
+
* @param {Number} pageNum - The page number of the rendered page
|
|
578
|
+
* @returns {Promise}
|
|
579
|
+
*/
|
|
580
|
+
updateMatches: function updateMatches(pageNum) {
|
|
581
|
+
return textManager.getPageContent(pageNum).then(function (pageContent) {
|
|
582
|
+
var selectedMatch;
|
|
600
583
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
584
|
+
if (currentMatch && currentMatch.page === pageNum) {
|
|
585
|
+
selectedMatch = currentMatch.index;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (pageContent) {
|
|
589
|
+
renderMatches(matches[pageNum - 1], pageContent, selectedMatch);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return pageNum;
|
|
593
|
+
});
|
|
594
|
+
},
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Destroys the search engine and frees the resources
|
|
598
|
+
*/
|
|
599
|
+
destroy: function destroy() {
|
|
600
|
+
textManager = null;
|
|
601
|
+
currentQuery = null;
|
|
602
|
+
currentMatch = null;
|
|
603
|
+
matches = null;
|
|
604
|
+
pages = null;
|
|
605
|
+
config = null;
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
}
|
|
618
609
|
|
|
619
|
-
|
|
610
|
+
return pdfjsSearchFactory;
|
|
620
611
|
|
|
621
612
|
});
|