1+ /* Feedback */
2+ document . addEventListener ( "DOMContentLoaded" , ( ) => {
3+
4+ const FEEDBACK_FORM_VERSION = "22.10" ;
5+ const FEEDBACK_API_ENDPOINT = "https://docs.groupdocs.com/api/feedback" ;
6+
7+ const feedbackData = { page : window . location . pathname , pageTitle : document . title , referrer : document . referrer , appVersion : FEEDBACK_FORM_VERSION } ;
8+ const feedbackForm = document . querySelector ( "#feedback" ) ;
9+
10+ init ( ) ;
11+
12+ function init ( ) {
13+ if ( ! feedbackForm )
14+ return ;
15+
16+ feedbackForm . querySelector ( '#feedback_yes' ) . addEventListener ( 'click' , yesClick ) ;
17+ feedbackForm . querySelector ( '#feedback_no' ) . addEventListener ( 'click' , noClick ) ;
18+ feedbackForm . querySelector ( '#feedback_yes_skip' ) . addEventListener ( 'click' , skip ) ;
19+ feedbackForm . querySelector ( '#feedback_no_skip' ) . addEventListener ( 'click' , skip ) ;
20+ feedbackForm . querySelector ( '#feedback_yes_send' ) . addEventListener ( 'click' , yesSend ) ;
21+ feedbackForm . querySelector ( '#feedback_no_send' ) . addEventListener ( 'click' , noSend ) ;
22+
23+ }
24+
25+ function yesClick ( ) {
26+ sendFeedbackData ( 1 ) ;
27+ setTab ( 'feedback_tab_yes' ) ;
28+ feedbackForm . querySelector ( '#feedback_yes_msg' ) . focus ( ) ;
29+
30+ }
31+ function noClick ( ) {
32+ sendFeedbackData ( - 1 ) ;
33+ setTab ( 'feedback_tab_no' ) ;
34+ feedbackForm . querySelector ( '#feedback_no_msg' ) . focus ( ) ;
35+ }
36+
37+ function yesSend ( ) {
38+ if ( ! validateMessage ( '#feedback_yes_msg' ) )
39+ return ;
40+
41+ sendFeedbackData ( 1 , feedbackForm . querySelector ( '#feedback_yes_msg' ) . value ) ;
42+ setTab ( 'feedback_tab_thanks' ) ;
43+
44+ }
45+
46+ function noSend ( ) {
47+ if ( ! validateMessage ( '#feedback_no_msg' ) )
48+ return ;
49+
50+ sendFeedbackData ( - 1 , feedbackForm . querySelector ( '#feedback_no_msg' ) . value ) ;
51+ setTab ( 'feedback_tab_thanks' ) ;
52+
53+ }
54+
55+
56+ function skip ( ) {
57+ setTab ( 'feedback_tab_thanks' ) ;
58+ }
59+
60+ function setTab ( id ) {
61+ feedbackForm . querySelectorAll ( '.gdoc-feedback__tab' ) . forEach ( ( tab ) => tab . classList . remove ( 'active' ) ) ;
62+ feedbackForm . querySelector ( '#' + id ) . classList . add ( 'active' ) ;
63+ }
64+
65+ function validateMessage ( selector ) {
66+ const $message = feedbackForm . querySelector ( selector ) ;
67+ if ( ! $message || ! $message . value || $message . value . trim ( ) === '' ) {
68+ $message . classList . add ( 'invalid' ) ;
69+ $message . focus ( ) ;
70+ return false ;
71+ }
72+ return true ;
73+ }
74+
75+ function sendFeedbackData ( rateValue , message ) {
76+ var data = { ...feedbackData , rateValue : rateValue } ;
77+ if ( message )
78+ data . message = message ;
79+
80+ return fetch ( FEEDBACK_API_ENDPOINT , {
81+ method : "POST" ,
82+ headers : { 'Content-Type' : 'application/json' } ,
83+ body : JSON . stringify ( data )
84+ } ) ;
85+ }
86+
87+
88+
89+ } ) ;
90+
91+
92+ /* To top button */
93+ document . addEventListener ( "DOMContentLoaded" , ( ) => {
94+ var MIN_SCROLL_ACTIVATE = window . outerHeight ;
95+ var gotopButton = document . querySelector ( '#gotop_button' ) ;
96+
97+ init ( ) ;
98+
99+ function init ( ) {
100+ if ( ! gotopButton )
101+ return ;
102+
103+ gotopButton . addEventListener ( 'click' , goTop ) ;
104+ document . addEventListener ( 'scroll' , updateVisibility ) ;
105+ }
106+
107+ function goTop ( ) {
108+ window . scrollTo ( 0 , 0 ) ;
109+ }
110+
111+ function updateVisibility ( e ) {
112+
113+ if ( window . scrollY > MIN_SCROLL_ACTIVATE ) {
114+ gotopButton . classList . add ( 'gdoc-gotop--visible' ) ;
115+ }
116+ else {
117+ gotopButton . classList . remove ( 'gdoc-gotop--visible' ) ;
118+ }
119+ }
120+
121+
122+ } ) ;
123+
124+
125+ /* Search block */
126+ document . addEventListener ( "DOMContentLoaded" , ( ) => {
127+ var MOBILE_SCREEN_WIDTH = 1024 ;
128+ var SEARCH_URL = "https://search.groupdocs.com/q/[query].html"
129+ var searchToggle = document . querySelector ( '#search_toggle' ) ;
130+ var searchClose = document . querySelector ( '#search_close' ) ;
131+ var menuBlock = document . querySelector ( '.gdoc-header__menu-inner' ) ;
132+ var brandBlock = document . querySelector ( '.gdoc-header__brand' ) ;
133+
134+ var searchBlock = document . querySelector ( '.gdoc-header__search' ) ;
135+ var searchInput = document . querySelector ( '#gdoc-search-input-ext' ) ;
136+
137+ var searchVisible = false ;
138+
139+ init ( ) ;
140+
141+ function init ( ) {
142+ if ( ! searchInput )
143+ return ;
144+
145+ searchInput . addEventListener ( 'keypress' , doSearch ) ;
146+ searchToggle . addEventListener ( 'click' , toggleSearch ) ;
147+ searchClose . addEventListener ( 'click' , toggleSearch ) ;
148+
149+ }
150+
151+ function doSearch ( e ) {
152+ if ( e . key !== 'Enter' ) { return ; }
153+
154+ var query = e . target . value . replace ( / / g, "-" ) ;
155+ var searchPageUrl = SEARCH_URL . replace ( '[query]' , query ) ;
156+ window . location . replace ( searchPageUrl ) ;
157+ return false ;
158+ }
159+
160+ function toggleSearch ( ) {
161+
162+ var isMobile = document . documentElement . clientWidth <= MOBILE_SCREEN_WIDTH ;
163+ searchVisible ? hideSearch ( isMobile ) : showSearch ( isMobile ) ;
164+
165+ }
166+
167+ function hideSearch ( isMobile ) {
168+ if ( ! searchVisible )
169+ return ;
170+ searchToggle . style . display = 'block' ;
171+ brandBlock . style . display = 'block' ;
172+ menuBlock . style . display = 'block' ;
173+ searchBlock . style . display = 'none' ;
174+ searchVisible = false ;
175+ }
176+
177+ function showSearch ( isMobile ) {
178+ if ( searchVisible )
179+ return ;
180+ searchToggle . style . display = 'none' ;
181+ if ( isMobile ) { brandBlock . style . display = 'none' ; }
182+ menuBlock . style . display = 'none' ;
183+ searchBlock . style . display = 'block' ;
184+ searchInput . focus ( ) ;
185+ searchVisible = true ;
186+ }
187+
188+
189+ } ) ;
190+
191+ /* Toc menu highlight */
192+ document . addEventListener ( 'DOMContentLoaded' , ( ) => {
193+
194+ var toc = document . querySelector ( '#TableOfContents' ) ;
195+ var anchors = document . querySelectorAll ( '.gdoc-page__anchor' ) ;
196+ var links = document . querySelectorAll ( '#TableOfContents a' ) ;
197+
198+ init ( ) ;
199+
200+ function init ( ) {
201+
202+ if ( ! toc )
203+ return ;
204+
205+ window . addEventListener ( 'resize' , updateToc ) ;
206+ window . addEventListener ( 'scroll' , updateToc ) ;
207+ updateToc ( ) ;
208+ }
209+
210+
211+ function updateToc ( ) {
212+
213+ for ( const anchor of anchors ) {
214+ if ( isInViewport ( anchor ) ) {
215+ setActiveToc ( anchor . attributes [ 'href' ] . value ) ;
216+ break ;
217+ }
218+ }
219+
220+ }
221+
222+ function setActiveToc ( href ) {
223+
224+ for ( const link of links ) {
225+ if ( link . attributes [ 'href' ] . value === href ) {
226+ link . classList . add ( 'active' ) ;
227+ }
228+ else {
229+ link . classList . remove ( 'active' ) ;
230+ }
231+ }
232+ }
233+
234+
235+ function isInViewport ( el ) {
236+
237+ const rect = el . getBoundingClientRect ( ) ;
238+
239+ return (
240+ rect . top >= 0 &&
241+ rect . left >= 0 &&
242+ rect . bottom <= ( window . innerHeight || document . documentElement . clientHeight ) &&
243+ rect . right <= ( window . innerWidth || document . documentElement . clientWidth )
244+ ) ;
245+
246+
247+ }
248+
249+
250+
251+ } ) ;
252+
253+
254+ /* Mobile Toc block */
255+ document . addEventListener ( "DOMContentLoaded" , ( ) => {
256+
257+ var tocToggle = document . querySelector ( '#TableOfContentsMobileHeader' ) ;
258+ var tocBlock = document . querySelector ( '#TableOfContentsMobile' ) ;
259+ var tocVisible = false ;
260+
261+ init ( ) ;
262+
263+ function init ( ) {
264+ if ( ! tocToggle )
265+ return ;
266+ tocToggle . addEventListener ( "click" , toggleToc ) ;
267+ }
268+
269+
270+ function toggleToc ( ) {
271+
272+ if ( tocVisible ) {
273+ tocBlock . style . display = 'none' ;
274+ tocToggle . classList . remove ( 'expanded' ) ;
275+ } else {
276+ tocBlock . style . display = 'block' ;
277+ tocToggle . classList . add ( 'expanded' ) ;
278+ }
279+
280+ tocVisible = ! tocVisible ;
281+ }
282+ } ) ;
283+
284+ /* Table filter */
285+ ( ( ) => {
286+ const tableFilter = document . getElementById ( 'tableFilter' ) ;
287+ const mainSection = document . querySelector ( 'article.gdoc-markdown' ) ;
288+
289+ if ( tableFilter && mainSection ) {
290+ const tables = mainSection . getElementsByTagName ( 'table' ) ;
291+
292+ tableFilter . addEventListener ( 'keyup' , function ( e ) {
293+ let filterValue = this . value . toLowerCase ( ) ;
294+ if ( e . code == "Escape" ) {
295+ this . value = '' ;
296+ filterValue = '' ;
297+ }
298+ for ( let t = 0 ; t < tables . length ; t ++ ) {
299+ let table = tables [ t ] ;
300+ let hasVisibleRows = false ;
301+ for ( let i = 1 ; i < table . rows . length ; i ++ ) { // Start from row 1 (skip header)
302+ let rowVisible = false ;
303+ for ( let j = 0 ; j < 1 ; j ++ ) { // or table.rows[i].cells.length
304+ const cellText = table . rows [ i ] . cells [ j ] . textContent . toLowerCase ( ) ;
305+ if ( cellText . includes ( filterValue ) ) {
306+ rowVisible = true ;
307+ break ;
308+ }
309+ }
310+ table . rows [ i ] . style . display = rowVisible ? 'table-row' : 'none' ;
311+
312+ if ( rowVisible ) {
313+ hasVisibleRows = true ;
314+ }
315+ }
316+
317+ let tableWrap = table . parentElement ;
318+ tableWrap . style . display = hasVisibleRows ? '' : 'none' ;
319+
320+ let prevElement = tableWrap . previousElementSibling ;
321+ prevElement . style . display = hasVisibleRows ? '' : 'none' ;
322+ while ( prevElement . className !== 'gdoc-page__anchorwrap' ) {
323+ prevElement = prevElement . previousElementSibling ;
324+ prevElement . style . display = hasVisibleRows ? '' : 'none' ;
325+ }
326+
327+ let nextElement = tableWrap . nextElementSibling ;
328+ if ( nextElement ) {
329+ if ( nextElement . className !== "gdoc-feedback" ) {
330+ nextElement . style . display = hasVisibleRows ? '' : 'none' ;
331+ while ( nextElement
332+ && nextElement . className !== 'gdoc-page__anchorwrap'
333+ && nextElement . className !== "gdoc-feedback" )
334+ {
335+ nextElement . style . display = hasVisibleRows ? '' : 'none' ;
336+ nextElement = nextElement . nextElementSibling ;
337+ }
338+ }
339+ }
340+ }
341+ } ) ;
342+ }
343+ } ) ( ) ;
0 commit comments