diff options
author | Sarah German <sgerman@gitlab.com> | 2023-04-15 02:05:15 +0300 |
---|---|---|
committer | Sarah German <sgerman@gitlab.com> | 2023-04-15 02:05:15 +0300 |
commit | 9ab519ec9ac2b8892014557b77d85d3d2c3de592 (patch) | |
tree | 6e63e8a425d8d223154d430e6a57a75b7c4f3e48 | |
parent | 28ad2f87e668641955813893063f9637a3941a21 (diff) |
Prevent layout shift when loading homepage search1605-gps-layout-shift
-rw-r--r-- | content/assets/stylesheets/_landing.scss | 9 | ||||
-rw-r--r-- | content/assets/stylesheets/stylesheet.scss | 6 | ||||
-rw-r--r-- | content/frontend/search/google.js | 52 | ||||
-rw-r--r-- | content/frontend/search/search_results.js | 18 | ||||
-rw-r--r-- | content/index.erb | 7 | ||||
-rw-r--r-- | layouts/default.html | 2 | ||||
-rw-r--r-- | layouts/head.html | 1 | ||||
-rw-r--r-- | layouts/header.html | 2 | ||||
-rw-r--r-- | layouts/search.html | 2 |
9 files changed, 85 insertions, 14 deletions
diff --git a/content/assets/stylesheets/_landing.scss b/content/assets/stylesheets/_landing.scss index c3e4ecc0..28dc29ee 100644 --- a/content/assets/stylesheets/_landing.scss +++ b/content/assets/stylesheets/_landing.scss @@ -72,10 +72,19 @@ border-radius: 0.25rem; width: 65%; + .gl-spinner-container { + position: relative; + top: 1rem; + } + @media (max-width: $bp-md) { width: 100%; } + .card-body { + height: 11.5rem; + } + .card-title { font-size: 3rem; line-height: 3.25rem; diff --git a/content/assets/stylesheets/stylesheet.scss b/content/assets/stylesheets/stylesheet.scss index 3295f250..beefe9a2 100644 --- a/content/assets/stylesheets/stylesheet.scss +++ b/content/assets/stylesheets/stylesheet.scss @@ -694,11 +694,13 @@ table.gstl_50 { } // Interior pages: nav bar search form .navbar-nav { - div.gsc-control-searchbox-only { + div.gsc-control-cse { transition: width 0.3s ease-in-out; width: 12rem; + border-width: 0; + background-color: transparent; } - div.gsc-control-searchbox-only:focus-within { + div.gsc-control-cse:focus-within { width: 18rem; } form.gsc-search-box { diff --git a/content/frontend/search/google.js b/content/frontend/search/google.js index 91e3787b..c5ff839f 100644 --- a/content/frontend/search/google.js +++ b/content/frontend/search/google.js @@ -1,18 +1,58 @@ +/* global google */ + import Vue from 'vue'; -import GoogleResults from './components/google_results.vue'; -import SearchForm from './components/search_form.vue'; +import { GlLoadingIcon } from '@gitlab/ui'; -const mountVue = (el, Component) => { +const mountVue = (el, Component, Props = {}) => { return new Vue({ el, components: { Component }, render(createElement) { - return createElement(Component); + return createElement(Component, { + props: Props, + }); }, }); }; +const renderSearchElement = () => { + const spinner = document.querySelector('.gl-spinner-container'); + if (spinner) spinner.remove(); + + google.search.cse.element.render({ + div: 'gl-gse-form', + attributes: { + autoComplete: true, + resultsUrl: '/search/', + }, + tag: 'search', + }); +}; +const loaderCallback = () => { + if (document.readyState === 'complete') { + renderSearchElement(); + } else { + google.setOnLoadCallback(renderSearchElement, true); + } +}; +// eslint-disable-next-line no-underscore-dangle +window.__gcse = { + parsetags: 'explicit', + callback: loaderCallback, +}; + +const loadGSElements = () => { + const gcse = document.createElement('script'); + gcse.type = 'text/javascript'; + gcse.async = true; + gcse.src = 'https://cse.google.com/cse.js?cx=97494f9fe316a426d'; + const s = document.getElementsByTagName('script')[0]; + s.parentNode.insertBefore(gcse, s); +}; + document.addEventListener('DOMContentLoaded', () => { - mountVue('.js-google-search', GoogleResults); - mountVue('.js-search-form', SearchForm); + mountVue('.search-loader', GlLoadingIcon, { + size: 'lg', + }); + loadGSElements(); }); diff --git a/content/frontend/search/search_results.js b/content/frontend/search/search_results.js new file mode 100644 index 00000000..91e3787b --- /dev/null +++ b/content/frontend/search/search_results.js @@ -0,0 +1,18 @@ +import Vue from 'vue'; +import GoogleResults from './components/google_results.vue'; +import SearchForm from './components/search_form.vue'; + +const mountVue = (el, Component) => { + return new Vue({ + el, + components: { Component }, + render(createElement) { + return createElement(Component); + }, + }); +}; + +document.addEventListener('DOMContentLoaded', () => { + mountVue('.js-google-search', GoogleResults); + mountVue('.js-search-form', SearchForm); +}); diff --git a/content/index.erb b/content/index.erb index b03183ef..97c2f97d 100644 --- a/content/index.erb +++ b/content/index.erb @@ -13,14 +13,15 @@ title: GitLab Documentation <div class="row"> <div class="col d-flex justify-content-center"> <div class="card search gl-mt-6 gl-py-2"> - <div class="card-body gl-pb-7"> - <h5 class="card-title gl-pb-4">Search the docs</h5> + <div class="card-body"> + <h5 class="card-title gl-pb-2">Search the docs</h5> <% if @item[:searchbar].nil? %> <% unless @item.identifier.to_s.split('/')[1] == 'search' %> <% if @config[:search_backend] == "algolia" %> <div id="docsearch" class="gl-mb-4 gl-display-flex gl-justify-content-center"></div> <% elsif @config[:search_backend] == "google" %> - <div class="gcse-searchbox-only" enableAutoComplete="true" data-resultsUrl="/search/"></div> + <div class="search-loader"></div> + <div id="gl-gse-form"></div> <% else %> <div class="js-search-form"></div> <% end %> diff --git a/layouts/default.html b/layouts/default.html index ce246af3..3340e19c 100644 --- a/layouts/default.html +++ b/layouts/default.html @@ -72,6 +72,8 @@ <script src="<%= @items['/frontend/shared/global_imports.*'].path %>"></script> <% if @config[:search_backend] == "algolia" %> <script src="<%= @items['/frontend/search/docsearch.*'].path %>"></script> + <% elsif @config[:search_backend] == "google" %> + <script src="<%= @items['/frontend/search/google.*'].path %>"></script> <% elsif @config[:search_backend] == "lunr" %> <script src="<%= @items['/frontend/search/lunrsearch.*'].path %>"></script> <% end %> diff --git a/layouts/head.html b/layouts/head.html index 2a99649a..99284d35 100644 --- a/layouts/head.html +++ b/layouts/head.html @@ -32,7 +32,6 @@ <% if @config[:search_backend] == "google" && @config[:google_search_key] %> <script>const GOOGLE_SEARCH_KEY = "<%= @config[:google_search_key] %>";</script> -<script async src="https://cse.google.com/cse.js?cx=97494f9fe316a426d"></script> <% end %> <!-- Enable CSP headers --> diff --git a/layouts/header.html b/layouts/header.html index 8526c79a..ed9815ad 100644 --- a/layouts/header.html +++ b/layouts/header.html @@ -15,7 +15,7 @@ <% if @config[:search_backend] == "algolia" %> <div id="docsearch" class="gl-my-3 gl-md-mt-0 gl-md-mb-0"></div> <% elsif @config[:search_backend] == "google" %> - <div class="gcse-searchbox-only" enableAutoComplete="true" data-resultsUrl="/search/"></div> + <div id="gl-gse-form"></div> <% else %> <div class="js-search-form"></div> <% end %> diff --git a/layouts/search.html b/layouts/search.html index bf9aea2b..85456dd1 100644 --- a/layouts/search.html +++ b/layouts/search.html @@ -7,7 +7,7 @@ <link rel="stylesheet" href="/frontend/search/instantsearch.css"> <script src="<%= @items['/frontend/search/instantsearch.*'].path %>"></script> <% elsif @config[:search_backend] == "google" %> - <script src="<%= @items['/frontend/search/google.*'].path %>"></script> + <script src="<%= @items['/frontend/search/search_results.*'].path %>"></script> <% else %> <script src="/assets/javascripts/lunr.min.js"></script> <script src="<%= @items['/frontend/search/lunrsearch.*'].path %>"></script> |