[embed] Add search bar

This commit is contained in:
JuliaSvinareva 2022-04-27 22:12:59 +03:00
parent b5ade7b338
commit 4f5ed97786
12 changed files with 728 additions and 2 deletions

View file

@ -0,0 +1,77 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
!window.common && (window.common = {});
!common.view && (common.view = {});
common.view.SearchBar = new(function() {
var tpl = '<div class="asc-window search-window" style="display: none;">' +
'<div class="body">{body}</div>' +
'</div>';
var tplBody = '<input type="text" id="search-bar-text" placeholder="{textFind}" autocomplete="off">' +
'<div class="tools">' +
'<button id="search-bar-back" class="svg-icon search-arrow-up"></button>' +
'<button id="search-bar-next" class="svg-icon search-arrow-down"></button>' +
'<button id="search-bar-close" class="svg-icon search-close"></button>' +
'</div>';
return {
create: function(parent) {
!parent && (parent = 'body');
var _$dlg = $(tpl
.replace(/\{body}/, tplBody)
.replace(/\{textFind}/, this.textFind))
.appendTo(parent)
.attr('id', 'dlg-search');
return _$dlg;
},
disableNavButtons: function (resultNumber, allResults) {
var disable = $('#search-bar-text').val() === '';
$('#search-bar-back').attr({disabled: disable || !allResults || resultNumber === 0});
$('#search-bar-next').attr({disabled: disable || resultNumber + 1 === allResults});
},
textFind: 'Find'
};
})();

View file

@ -1,4 +1,4 @@
<svg width="380" height="40" viewBox="0 0 380 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="440" height="40" viewBox="0 0 440 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon-menu-sprite Embedded Viewer">
<g id="view-settings">
<path id="Vector" d="M17 26H3V27H17V26Z" fill="white"/>
@ -148,5 +148,23 @@
<g id="close_2">
<path id="Vector 73_2" d="M366 5L375 14M375 5L366 14" stroke="black" stroke-width="1.5"/>
</g>
<g id="search">
<path id="Union_27" fill-rule="evenodd" clip-rule="evenodd" d="M393 8.5C393 10.9853 390.985 13 388.5 13C386.015 13 384 10.9853 384 8.5C384 6.01472 386.015 4 388.5 4C390.985 4 393 6.01472 393 8.5ZM392.02 12.7266C391.066 13.5217 389.839 14 388.5 14C385.462 14 383 11.5376 383 8.5C383 5.46243 385.462 3 388.5 3C391.538 3 394 5.46243 394 8.5C394 9.83875 393.522 11.0658 392.727 12.0195L396.854 16.1465L396.146 16.8536L392.02 12.7266Z" fill="black"/>
</g>
<g id="search_2">
<path id="Union_28" fill-rule="evenodd" clip-rule="evenodd" d="M393 28.5C393 30.9853 390.985 33 388.5 33C386.015 33 384 30.9853 384 28.5C384 26.0147 386.015 24 388.5 24C390.985 24 393 26.0147 393 28.5ZM392.02 32.7266C391.066 33.5217 389.839 34 388.5 34C385.462 34 383 31.5376 383 28.5C383 25.4624 385.462 23 388.5 23C391.538 23 394 25.4624 394 28.5C394 29.8387 393.522 31.0658 392.727 32.0195L396.854 36.1465L396.146 36.8536L392.02 32.7266Z" fill="white"/>
</g>
<g id="arrow-up">
<path id="Union_29" fill-rule="evenodd" clip-rule="evenodd" d="M410 6.29297L410.354 6.64652L415.854 12.1465L415.146 12.8536L410 7.70718L404.854 12.8536L404.146 12.1465L409.646 6.64652L410 6.29297Z" fill="black"/>
</g>
<g id="arrow-up_2">
<path id="Union_30" fill-rule="evenodd" clip-rule="evenodd" d="M410 26.293L410.354 26.6465L415.854 32.1465L415.146 32.8536L410 27.7072L404.854 32.8536L404.146 32.1465L409.646 26.6465L410 26.293Z" fill="white"/>
</g>
<g id="arrow-down">
<path id="Union_31" fill-rule="evenodd" clip-rule="evenodd" d="M430 13.7071L430.354 13.3536L435.854 7.85359L435.146 7.14648L430 12.2929L424.854 7.14648L424.146 7.85359L429.646 13.3536L430 13.7071Z" fill="black"/>
</g>
<g id="arrow-down_2">
<path id="Union_32" fill-rule="evenodd" clip-rule="evenodd" d="M430 33.7071L430.354 33.3536L435.854 27.8536L435.146 27.1465L430 32.2929L424.854 27.1465L424.146 27.8536L429.646 33.3536L430 33.7071Z" fill="white"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -503,7 +503,7 @@
@icon-height: 20px;
.svg-icon {
background: data-uri('../../../../common/embed/resources/img/icon-menu-sprite.svg') no-repeat;
background-size: @icon-width*19 @icon-height*2;
background-size: @icon-width*22 @icon-height*2;
&.download {
background-position: -@icon-width 0;
@ -557,6 +557,18 @@
&.more-vertical {
background-position: -@icon-width*14 0;
}
&.search-close {
background-position: -@icon-width*18 0;
}
&.search {
background-position: -@icon-width*19 0;
}
&.search-arrow-up {
background-position: -@icon-width*20 0;
}
&.search-arrow-down {
background-position: -@icon-width*21 0;
}
}
.mi-icon {
@ -785,4 +797,73 @@
font-weight: normal;
}
}
}
#id-search {
button.active {
background-color: @btnActiveColor !important;
background-position: -@icon-width*19 -@icon-height;
}
}
.search-window {
width: 301px;
height: 54px;
z-index: 50;
position: fixed;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
border-radius: 5px;
border: solid 1px #CBCBCB;
.body {
width: 100%;
height: 100%;
border-radius: 5px;
background-color: #FFFFFF;
display: flex;
padding: 16px;
input {
width: 192px;
height: 22px;
border-radius: 2px;
box-shadow: none;
border: solid 1px #CFCFCF;
padding: 1px 3px;
color: #444444;
font-size: 11px;
&::placeholder {
color: #CFCFCF;
}
&:focus {
border-color: #848484;
outline: 0;
}
}
.tools {
display: flex;
button {
border: none;
margin-left: 7px;
cursor: pointer;
width: 20px;
height: 20px;
opacity: 0.8;
&:hover:not(:disabled) {
background-color: #d8dadc;
}
&:disabled {
opacity: 0.4;
cursor: default;
}
}
}
}
}

View file

@ -198,6 +198,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>
<div id="id-pages" class="item margin-right-small" style="vertical-align: middle;"><input id="page-number" class="form-control input-xs masked" type="text" value="0"><span class="text" id="pages" tabindex="-1">of 0</span></div>
<div id="id-submit-group" style="display: inline-block;"><button id="id-btn-submit" class="control-btn has-caption margin-left-small margin-right-small colored"><span class="caption"></span></button></div>
<div id="box-tools" class="dropdown">
@ -255,6 +256,8 @@
<script type="text/javascript" src="../../common/embed/lib/view/LoadMask.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/controller/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/SearchBar.js"></script>
<script type="text/javascript" src="js/SearchBar.js"></script>
<script type="text/javascript" src="js/ApplicationView.js"></script>
<script type="text/javascript" src="js/ApplicationController.js"></script>
<script type="text/javascript" src="js/application.js"></script>

View file

@ -75,6 +75,8 @@ DE.ApplicationController = new(function(){
embedConfig = $.extend(embedConfig, data.config.embedded);
common.controller.modals.init(embedConfig);
common.controller.SearchBar.init(embedConfig);
// Docked toolbar
if (embedConfig.toolbarDocked === 'bottom') {
@ -450,6 +452,10 @@ DE.ApplicationController = new(function(){
embed: '#idt-embed'
});
common.controller.SearchBar.attach({
search: '#id-search'
});
api.asc_registerCallback('asc_onStartAction', onLongActionBegin);
api.asc_registerCallback('asc_onEndAction', onLongActionEnd);
api.asc_registerCallback('asc_onMouseMoveStart', onDocMouseMoveStart);
@ -912,6 +918,8 @@ DE.ApplicationController = new(function(){
Common.Gateway.on('opendocument', loadDocument);
Common.Gateway.on('showmessage', onExternalMessage);
Common.Gateway.appReady();
common.controller.SearchBar.setApi(api);
}
return me;

View file

@ -0,0 +1,175 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
+function () {
!window.common && (window.common = {});
!common.controller && (common.controller = {});
common.controller.SearchBar = new(function() {
var $searchBar,
$searchBtn,
$searchInput,
appConfig,
api,
_state = {
searchText: ''
},
_lastInputChange,
_searchTimer;
var setApi = function (appApi) {
api = appApi;
if (api) {
api.asc_registerCallback('asc_onSetSearchCurrent', onApiUpdateSearchCurrent);
}
};
var create = function () {
$searchBar = common.view.SearchBar.create();
if (appConfig.toolbarDocked === 'bottom') {
$searchBar.css({'right': '45px', 'bottom': '31px'});
} else {
$searchBar.css({'right': '45px', 'top': '31px'});
}
$searchInput = $searchBar.find('#search-bar-text');
$searchInput.on('input', function(e){
common.view.SearchBar.disableNavButtons();
onInputSearchChange($searchInput.val());
}).on('keydown', function (e) {
onSearchNext('keydown', $searchInput.val(), e);
});
$searchBar.find('#search-bar-back').on('click', function(e){
onSearchNext('back', $searchInput.val());
});
$searchBar.find('#search-bar-next').on('click', function(e){
onSearchNext('next', $searchInput.val());
});
$searchBar.find('#search-bar-close').on('click', function(e){
highlightResults(false);
$searchBar.hide();
$searchBtn.find('button').button('toggle');
});
common.view.SearchBar.disableNavButtons();
};
var attachToView = function(config) {
if ( !$searchBar ) {
create();
}
$searchBtn = $(config.search);
$searchBtn.on('click', function(e){
if ($searchBar.is(':visible')) {
highlightResults(false);
$searchBar.hide();
} else {
highlightResults(true);
var text = (api && api.asc_GetSelectedText()) || _state.searchText;
$searchInput.val(text);
(text.length > 0) && onInputSearchChange(text);
$searchBar.show();
$searchInput.focus();
$searchInput.select();
}
$searchBtn.find('button').button('toggle');
});
};
var onInputSearchChange = function (text) {
if (_state.searchText !== text) {
_state.newSearchText = text;
_lastInputChange = (new Date());
if (_searchTimer === undefined) {
_searchTimer = setInterval(function() {
if ((new Date()) - _lastInputChange < 400) return;
_state.searchText = _state.newSearchText;
(_state.newSearchText !== '') && onQuerySearch();
clearInterval(_searchTimer);
_searchTimer = undefined;
}, 10);
}
}
};
var onQuerySearch = function (d, w) {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(_state.searchText);
searchSettings.put_MatchCase(false);
searchSettings.put_WholeWords(false);
if (!api.asc_findText(searchSettings, d != 'back')) {
common.view.SearchBar.disableNavButtons();
return false;
}
return true;
};
var onSearchNext = function (type, text, e) {
if (text && text.length > 0 && (type === 'keydown' && e.keyCode === 13 || type !== 'keydown')) {
_state.searchText = text;
if (onQuerySearch(type) && _searchTimer) {
clearInterval(_searchTimer);
_searchTimer = undefined;
}
}
};
var onApiUpdateSearchCurrent = function (current, all) {
common.view.SearchBar.disableNavButtons(current, all);
};
var highlightResults = function (val) {
if (_state.isHighlightedResults !== val) {
api.asc_selectSearchingResults(val);
_state.isHighlightedResults = val;
}
};
return {
init: function(config) { appConfig = config; },
attach: attachToView,
setApi: setApi
};
});
}();

View file

@ -250,6 +250,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>
<div class="item margin-right-small"><input id="page-number" class="form-control input-xs masked" type="text" value="0"><span class="text" id="pages" tabindex="-1">of 0</span></div>
<div id="box-tools" class="dropdown">
<button class="control-btn svg-icon more-vertical"></button>
@ -305,6 +306,8 @@
<script type="text/javascript" src="../../common/embed/lib/view/LoadMask.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/controller/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/SearchBar.js"></script>
<script type="text/javascript" src="js/SearchBar.js"></script>
<script type="text/javascript" src="js/ApplicationView.js"></script>
<script type="text/javascript" src="js/ApplicationController.js"></script>
<script type="text/javascript" src="js/application.js"></script>

View file

@ -72,6 +72,7 @@ PE.ApplicationController = new(function(){
embedConfig = $.extend(embedConfig, data.config.embedded);
common.controller.modals.init(embedConfig);
common.controller.SearchBar.init(embedConfig);
// Docked toolbar
if (embedConfig.toolbarDocked === 'bottom') {
@ -293,6 +294,10 @@ PE.ApplicationController = new(function(){
embed: '#idt-embed'
});
common.controller.SearchBar.attach({
search: '#id-search'
});
api.asc_registerCallback('asc_onMouseMoveStart', onDocMouseMoveStart);
api.asc_registerCallback('asc_onMouseMoveEnd', onDocMouseMoveEnd);
api.asc_registerCallback('asc_onMouseMove', onDocMouseMove);
@ -720,6 +725,8 @@ PE.ApplicationController = new(function(){
Common.Gateway.on('opendocument', loadDocument);
Common.Gateway.on('showmessage', onExternalMessage);
Common.Gateway.appReady();
common.controller.SearchBar.setApi(api);
}
return me;

View file

@ -0,0 +1,165 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
+function () {
!window.common && (window.common = {});
!common.controller && (common.controller = {});
common.controller.SearchBar = new(function() {
var $searchBar,
$searchBtn,
$searchInput,
appConfig,
api,
_state = {
searchText: ''
},
_lastInputChange,
_searchTimer;
var setApi = function (appApi) {
api = appApi;
if (api) {
api.asc_registerCallback('asc_onSetSearchCurrent', onApiUpdateSearchCurrent);
}
};
var create = function () {
$searchBar = common.view.SearchBar.create();
if (appConfig.toolbarDocked === 'bottom') {
$searchBar.css({'right': '45px', 'bottom': '31px'});
} else {
$searchBar.css({'right': '45px', 'top': '31px'});
}
$searchInput = $searchBar.find('#search-bar-text');
$searchInput.on('input', function(e){
common.view.SearchBar.disableNavButtons();
onInputSearchChange($searchInput.val());
}).on('keydown', function (e) {
onSearchNext('keydown', $searchInput.val(), e);
});
$searchBar.find('#search-bar-back').on('click', function(e){
onSearchNext('back', $searchInput.val());
});
$searchBar.find('#search-bar-next').on('click', function(e){
onSearchNext('next', $searchInput.val());
});
$searchBar.find('#search-bar-close').on('click', function(e){
$searchBar.hide();
$searchBtn.find('button').button('toggle');
});
common.view.SearchBar.disableNavButtons();
};
var attachToView = function(config) {
if ( !$searchBar ) {
create();
}
$searchBtn = $(config.search);
$searchBtn.on('click', function(e){
if ($searchBar.is(':visible')) {
$searchBar.hide();
} else {
var text = (api && api.asc_GetSelectedText()) || _state.searchText;
$searchInput.val(text);
(text.length > 0) && onInputSearchChange(text);
$searchBar.show();
$searchInput.focus();
$searchInput.select();
}
$searchBtn.find('button').button('toggle');
});
};
var onInputSearchChange = function (text) {
if (_state.searchText !== text) {
_state.newSearchText = text;
_lastInputChange = (new Date());
if (_searchTimer === undefined) {
_searchTimer = setInterval(function() {
if ((new Date()) - _lastInputChange < 400) return;
_state.searchText = _state.newSearchText;
(_state.newSearchText !== '') && onQuerySearch();
clearInterval(_searchTimer);
_searchTimer = undefined;
}, 10);
}
}
};
var onQuerySearch = function (d, w) {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(_state.searchText);
searchSettings.put_MatchCase(false);
searchSettings.put_WholeWords(false);
if (!api.asc_findText(searchSettings, d != 'back')) {
common.view.SearchBar.disableNavButtons();
return false;
}
return true;
};
var onSearchNext = function (type, text, e) {
if (text && text.length > 0 && (type === 'keydown' && e.keyCode === 13 || type !== 'keydown')) {
_state.searchText = text;
if (onQuerySearch(type) && _searchTimer) {
clearInterval(_searchTimer);
_searchTimer = undefined;
}
}
};
var onApiUpdateSearchCurrent = function (current, all) {
common.view.SearchBar.disableNavButtons(current, all);
};
return {
init: function(config) { appConfig = config; },
attach: attachToView,
setApi: setApi
};
});
}();

View file

@ -224,6 +224,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>
<div id="box-tools" class="dropdown">
<button class="control-btn svg-icon more-vertical"></button>
</div>
@ -281,6 +282,8 @@
<script type="text/javascript" src="../../common/embed/lib/view/LoadMask.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/controller/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/SearchBar.js"></script>
<script type="text/javascript" src="js/SearchBar.js"></script>
<script type="text/javascript" src="js/ApplicationView.js"></script>
<script type="text/javascript" src="js/ApplicationController.js"></script>
<script type="text/javascript" src="js/application.js"></script>

View file

@ -74,6 +74,7 @@ SSE.ApplicationController = new(function(){
embedConfig = $.extend(embedConfig, data.config.embedded);
common.controller.modals.init(embedConfig);
common.controller.SearchBar.init(embedConfig);
// Docked toolbar
if (embedConfig.toolbarDocked === 'bottom') {
@ -232,6 +233,10 @@ SSE.ApplicationController = new(function(){
embed: '#idt-embed'
});
common.controller.SearchBar.attach({
search: '#id-search'
});
api.asc_registerCallback('asc_onMouseMove', onApiMouseMove);
api.asc_registerCallback('asc_onHyperlinkClick', common.utils.openLink);
api.asc_registerCallback('asc_onDownloadUrl', onDownloadUrl);
@ -666,6 +671,8 @@ SSE.ApplicationController = new(function(){
Common.Gateway.on('opendocument', loadDocument);
Common.Gateway.on('showmessage', onExternalMessage);
Common.Gateway.appReady();
common.controller.SearchBar.setApi(api);
}
return me;

View file

@ -0,0 +1,179 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
+function () {
!window.common && (window.common = {});
!common.controller && (common.controller = {});
common.controller.SearchBar = new(function() {
var $searchBar,
$searchBtn,
$searchInput,
appConfig,
api,
_state = {
searchText: ''
},
_lastInputChange,
_searchTimer;
var setApi = function (appApi) {
api = appApi;
if (api) {
api.asc_registerCallback('asc_onSetSearchCurrent', onApiUpdateSearchCurrent);
}
};
var create = function () {
$searchBar = common.view.SearchBar.create();
if (appConfig.toolbarDocked === 'bottom') {
$searchBar.css({'right': '45px', 'bottom': '31px'});
} else {
$searchBar.css({'right': '45px', 'top': '31px'});
}
$searchInput = $searchBar.find('#search-bar-text');
$searchInput.on('input', function(e){
common.view.SearchBar.disableNavButtons();
onInputSearchChange($searchInput.val());
}).on('keydown', function (e) {
onSearchNext('keydown', $searchInput.val(), e);
});
$searchBar.find('#search-bar-back').on('click', function(e){
onSearchNext('back', $searchInput.val());
});
$searchBar.find('#search-bar-next').on('click', function(e){
onSearchNext('next', $searchInput.val());
});
$searchBar.find('#search-bar-close').on('click', function(e){
highlightResults(false);
$searchBar.hide();
$searchBtn.find('button').button('toggle');
});
common.view.SearchBar.disableNavButtons();
};
var attachToView = function(config) {
if ( !$searchBar ) {
create();
}
$searchBtn = $(config.search);
$searchBtn.on('click', function(e){
if ($searchBar.is(':visible')) {
highlightResults(false);
$searchBar.hide();
} else {
highlightResults(true);
var text = (api && api.asc_GetSelectedText()) || _state.searchText;
$searchInput.val(text);
(text.length > 0) && onInputSearchChange(text);
$searchBar.show();
$searchInput.focus();
$searchInput.select();
}
$searchBtn.find('button').button('toggle');
});
};
var onInputSearchChange = function (text) {
if (_state.searchText !== text) {
_state.newSearchText = text;
_lastInputChange = (new Date());
if (_searchTimer === undefined) {
_searchTimer = setInterval(function() {
if ((new Date()) - _lastInputChange < 400) return;
_state.searchText = _state.newSearchText;
(_state.newSearchText !== '') && onQuerySearch();
clearInterval(_searchTimer);
_searchTimer = undefined;
}, 10);
}
}
};
var onQuerySearch = function (d, w) {
var options = new Asc.asc_CFindOptions();
options.asc_setFindWhat(_state.searchText);
options.asc_setScanForward(d != 'back');
options.asc_setIsMatchCase(false);
options.asc_setIsWholeCell(false);
options.asc_setScanOnOnlySheet(Asc.c_oAscSearchBy.Sheet);
options.asc_setScanByRows(true);
options.asc_setLookIn(Asc.c_oAscFindLookIn.Formulas);
if (!api.asc_findText(options)) {
common.view.SearchBar.disableNavButtons();
return false;
}
return true;
};
var onSearchNext = function (type, text, e) {
if (text && text.length > 0 && (type === 'keydown' && e.keyCode === 13 || type !== 'keydown')) {
_state.searchText = text;
if (onQuerySearch(type) && _searchTimer) {
clearInterval(_searchTimer);
_searchTimer = undefined;
}
}
};
var onApiUpdateSearchCurrent = function (current, all) {
common.view.SearchBar.disableNavButtons(current, all);
};
var highlightResults = function (val) {
if (_state.isHighlightedResults !== val) {
api.asc_selectSearchingResults(val);
_state.isHighlightedResults = val;
}
};
return {
init: function(config) { appConfig = config; },
attach: attachToView,
setApi: setApi
};
});
}();