From 4f5ed9778611730d9adfd090d2b5ff1a852dbbfa Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 27 Apr 2022 22:12:59 +0300 Subject: [PATCH] [embed] Add search bar --- apps/common/embed/lib/view/SearchBar.js | 77 ++++++++ .../embed/resources/img/icon-menu-sprite.svg | 20 +- apps/common/embed/resources/less/common.less | 83 +++++++- apps/documenteditor/embed/index.html | 3 + .../embed/js/ApplicationController.js | 8 + apps/documenteditor/embed/js/SearchBar.js | 175 +++++++++++++++++ apps/presentationeditor/embed/index.html | 3 + .../embed/js/ApplicationController.js | 7 + apps/presentationeditor/embed/js/SearchBar.js | 165 ++++++++++++++++ apps/spreadsheeteditor/embed/index.html | 3 + .../embed/js/ApplicationController.js | 7 + apps/spreadsheeteditor/embed/js/SearchBar.js | 179 ++++++++++++++++++ 12 files changed, 728 insertions(+), 2 deletions(-) create mode 100644 apps/common/embed/lib/view/SearchBar.js create mode 100644 apps/documenteditor/embed/js/SearchBar.js create mode 100644 apps/presentationeditor/embed/js/SearchBar.js create mode 100644 apps/spreadsheeteditor/embed/js/SearchBar.js diff --git a/apps/common/embed/lib/view/SearchBar.js b/apps/common/embed/lib/view/SearchBar.js new file mode 100644 index 000000000..7800e132b --- /dev/null +++ b/apps/common/embed/lib/view/SearchBar.js @@ -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 = ''; + var tplBody = '' + + '
' + + '' + + '' + + '' + + '
'; + + 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' + + }; +})(); \ No newline at end of file diff --git a/apps/common/embed/resources/img/icon-menu-sprite.svg b/apps/common/embed/resources/img/icon-menu-sprite.svg index 97b51fd3e..c04600809 100644 --- a/apps/common/embed/resources/img/icon-menu-sprite.svg +++ b/apps/common/embed/resources/img/icon-menu-sprite.svg @@ -1,4 +1,4 @@ - + @@ -148,5 +148,23 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/common/embed/resources/less/common.less b/apps/common/embed/resources/less/common.less index 1d6c7bbf0..5d588ee1d 100644 --- a/apps/common/embed/resources/less/common.less +++ b/apps/common/embed/resources/less/common.less @@ -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; + } + } + } + } } \ No newline at end of file diff --git a/apps/documenteditor/embed/index.html b/apps/documenteditor/embed/index.html index b4ba894b1..c6b115212 100644 --- a/apps/documenteditor/embed/index.html +++ b/apps/documenteditor/embed/index.html @@ -198,6 +198,7 @@
+
of 0
+
of 0
+ @@ -281,6 +282,8 @@ + + diff --git a/apps/spreadsheeteditor/embed/js/ApplicationController.js b/apps/spreadsheeteditor/embed/js/ApplicationController.js index 5e0d7bcf4..aaebbc0f5 100644 --- a/apps/spreadsheeteditor/embed/js/ApplicationController.js +++ b/apps/spreadsheeteditor/embed/js/ApplicationController.js @@ -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; diff --git a/apps/spreadsheeteditor/embed/js/SearchBar.js b/apps/spreadsheeteditor/embed/js/SearchBar.js new file mode 100644 index 000000000..dfc5fe20b --- /dev/null +++ b/apps/spreadsheeteditor/embed/js/SearchBar.js @@ -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 + }; + }); +}(); \ No newline at end of file