|
20 | 20 | };
|
21 | 21 |
|
22 | 22 | var defaultConfig = {
|
23 |
| - allowedTags: '', |
24 | 23 | minQueryLength: 2,
|
25 | 24 | maxPreviewItems: 10,
|
26 | 25 | previewDelay: 500,
|
|
38 | 37 | };
|
39 | 38 | }
|
40 | 39 |
|
41 |
| - function isValidUrl(url) { |
42 |
| - var parser = document.createElement('a'); |
43 |
| - try { |
44 |
| - parser.href = url; |
45 |
| - return !!parser.hostname; |
46 |
| - } catch (e) { |
47 |
| - return false; |
48 |
| - } |
49 |
| - } |
50 |
| - |
51 |
| - // See http://phpjs.org/functions/strip_tags/ |
52 |
| - function stripTags(input, allowed) { |
53 |
| - allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); |
54 |
| - |
55 |
| - var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi; |
56 |
| - var commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi; |
57 |
| - |
58 |
| - return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) { |
59 |
| - return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; |
60 |
| - }); |
61 |
| - } |
62 |
| - |
63 | 40 | var initInstantSearch = function(el, config) {
|
64 | 41 | var $input = $(el);
|
65 | 42 | var $form = $input.closest('form');
|
66 | 43 | var $preview = $('<ul class="search-preview list-group"></ul>').appendTo($form);
|
67 | 44 |
|
68 |
| - config.noItemsFoundMessage = stripTags(config.noItemsFoundMessage); |
69 |
| - |
70 | 45 | var setPreviewItems = function(items) {
|
71 | 46 | $preview.empty();
|
72 | 47 |
|
|
80 | 55 | }
|
81 | 56 |
|
82 | 57 | var addItemToPreview = function(item) {
|
83 |
| - $preview.append('<li class="list-group-item"><a href="' + item.url + '">' + item.result + '</a></li>'); |
| 58 | + var $link = $('<a>').attr('href', item.url).text(item.result); |
| 59 | + var $li = $('<li class="list-group-item">').append($link); |
| 60 | + |
| 61 | + $preview.append($li); |
84 | 62 | }
|
85 | 63 |
|
86 | 64 | var noItemsFound = function() {
|
| 65 | + var $li = $('<li class="list-group-item">').text(config.noItemsFoundMessage); |
| 66 | + |
87 | 67 | $preview.empty();
|
88 |
| - $preview.append('<li class="list-group-item">' + config.noItemsFoundMessage + '</li>'); |
| 68 | + $preview.append($li); |
89 | 69 | }
|
90 | 70 |
|
91 | 71 | var updatePreview = function() {
|
92 |
| - if ($input.val().length < config.minQueryLength) { |
| 72 | + var query = $.trim($input.val()).replace(/\s{2,}/g, ' '); |
| 73 | + if (query.length < config.minQueryLength) { |
93 | 74 | $preview.empty();
|
94 | 75 | return;
|
95 | 76 | }
|
96 | 77 |
|
97 | 78 | $.getJSON($form.attr('action') + '?' + $form.serialize(), function(items) {
|
98 |
| - // Sanitize items |
99 |
| - var sanitizedItems = []; |
100 |
| - $.each(items, function(index, item) { |
101 |
| - // Url can contains a 'javascript:' code |
102 |
| - if (isValidUrl(item.url)) { |
103 |
| - sanitizedItems.push({ |
104 |
| - url: item.url, |
105 |
| - result: stripTags(item.result, config.allowedTags) |
106 |
| - }); |
107 |
| - } |
108 |
| - }); |
109 |
| - |
110 |
| - if (sanitizedItems.length === 0) { |
| 79 | + if (items.length === 0) { |
111 | 80 | noItemsFound();
|
112 | 81 | return;
|
113 | 82 | }
|
114 | 83 |
|
115 |
| - setPreviewItems(sanitizedItems); |
| 84 | + setPreviewItems(items); |
116 | 85 | });
|
117 | 86 | }
|
118 | 87 |
|
119 |
| - var debouncedUpdatePreview = debounce(updatePreview, config.previewDelay); |
120 |
| - |
121 | 88 | $input.focusout(function(e) {
|
122 | 89 | $preview.fadeOut();
|
123 | 90 | });
|
|
127 | 94 | updatePreview();
|
128 | 95 | });
|
129 | 96 |
|
130 |
| - $input.keyup(function(e) { |
131 |
| - debouncedUpdatePreview(); |
132 |
| - }); |
| 97 | + $input.keyup(debounce(updatePreview, config.previewDelay)); |
133 | 98 | }
|
134 | 99 | })(window.jQuery);
|
0 commit comments