content,internal: separate and rename fixed header ui code

Creates new files for unit fixed header ui
in preparation for future changes that diverge
from the existing fixed nav. Contains no code changes
outside of renamed css classes.

Change-Id: I450565deea86d88bb10c580f840d0cdd59c5c683
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/256540
Reviewed-by: Julie Qiu <julie@golang.org>
Trust: Jamal Carvalho <jamal@golang.org>
diff --git a/content/static/css/unit_details.css b/content/static/css/unit_details.css
index 34e2958..ab7a90d 100644
--- a/content/static/css/unit_details.css
+++ b/content/static/css/unit_details.css
@@ -5,6 +5,7 @@
  */
 
 @import './unit_header.css';
+@import './unit_fixed_header.css';
 @import './unit_readme.css';
 @import './unit_doc.css';
 @import './unit_directories.css';
diff --git a/content/static/css/unit_fixed_header.css b/content/static/css/unit_fixed_header.css
new file mode 100644
index 0000000..dc22b1c
--- /dev/null
+++ b/content/static/css/unit_fixed_header.css
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+.UnitFixedHeader {
+  background-color: var(--gray-10);
+  border-bottom: 1px solid var(--gray-8);
+  height: var(--header-height);
+  position: fixed;
+  top: 0;
+  left: 0;
+  transition: transform 100ms linear;
+  width: 100%;
+  z-index: 1000;
+}
+.UnitFixedHeader[aria-hidden='true'] {
+  transform: translateY(calc(var(--header-height) * -1));
+}
+.UnitFixedHeader [aria-hidden='true'] {
+  display: none;
+}
+.UnitFixedHeader-container {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  margin: 0 auto;
+  max-width: 75.75rem;
+  padding: 0 0.5rem;
+  position: relative;
+}
+.Site--wide .UnitFixedHeader-container {
+  max-width: none;
+}
+.UnitFixedHeader-logoLink {
+  margin-right: 1rem;
+}
+.UnitFixedHeader-logo {
+  display: block;
+  height: 1.695625;
+  width: 4.5rem;
+}
+.UnitFixedHeader-moduleInfo {
+  align-items: baseline;
+  display: flex;
+  flex-wrap: nowrap;
+  margin-right: 3rem;
+  min-width: 0;
+}
+.UnitFixedHeader-title {
+  font: 600 1.125rem/1.5 'Work Sans', arial, sans-serif;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.UnitFixedHeader-titleType {
+  display: none;
+}
+.UnitFixedHeader-titleType--small {
+  display: inline;
+}
+@media only screen and (min-width: 25rem) {
+  .UnitFixedHeader-titleType {
+    display: inline;
+  }
+  .UnitFixedHeader-titleType--small {
+    display: none;
+  }
+}
+.UnitFixedHeader .CopyToClipboardButton {
+  top: 0.1875rem;
+}
+.UnitFixedHeader-pathInput {
+  left: -100vw;
+  position: absolute;
+  top: -100vh;
+}
+.UnitFixedHeader-version {
+  color: var(--gray-2);
+  font-size: 0.6875rem;
+  position: relative;
+}
+@media only screen and (min-width: 37.5rem) {
+  .UnitFixedHeader-container {
+    padding: 0 1rem 0 1.5rem;
+  }
+  .UnitFixedHeader-logo {
+    height: 1.9541rem;
+    width: 5.1875rem;
+  }
+  .UnitFixedHeader-title {
+    font-size: 1.5rem;
+  }
+  .UnitFixedHeader .CopyToClipboardButton {
+    top: 0.0625rem;
+  }
+  .UnitFixedHeader-version {
+    top: -0.125rem;
+  }
+}
+.UnitFixedHeader-overflowingTabList {
+  display: flex;
+  flex: 1;
+  height: 100%;
+  min-width: 0;
+  position: relative;
+}
+.UnitFixedHeader [role='tablist'] {
+  display: flex;
+  flex: 1;
+  height: 100%;
+  justify-content: flex-end;
+  margin: 0;
+  padding: 0;
+}
+.UnitFixedHeader [role='tab'] + [role='tab'] {
+  margin-left: 1rem;
+}
+.UnitFixedHeader [role='tab'] {
+  border-bottom: 0.25rem solid transparent;
+  display: block;
+  height: 100%;
+  padding: 1.3125rem 0.5rem 0 0.5rem;
+  white-space: nowrap;
+}
+.UnitFixedHeader [role='tab']:hover {
+  border-bottom-color: var(--purple);
+  text-decoration: none;
+}
+.UnitFixedHeader [role='tab'][aria-selected='true'] {
+  border-bottom-color: var(--turq-dark);
+}
+.UnitFixedHeader [role='tab'][aria-hidden='true'] {
+  display: none;
+}
+.UnitFixedHeader [role='tab'][aria-disabled='true'],
+.UnitFixedHeader [role='tab'][aria-disabled='true']:hover {
+  border-bottom-color: transparent;
+  color: var(--gray-5);
+  cursor: not-allowed;
+}
+.UnitFixedHeader-overflowContainer {
+  display: none;
+  height: 1.5rem;
+  position: absolute;
+  right: 0.0625rem;
+  top: 1.125rem;
+  width: 1.5rem;
+}
+.UnitFixedHeader-overflowingTabList.is-overflowing {
+  padding-right: 1.5rem;
+}
+.UnitFixedHeader-overflowingTabList.is-overflowing .UnitFixedHeader-overflowContainer {
+  display: block;
+}
+.UnitFixedHeader-overflowImage {
+  fill: var(--gray-3);
+  height: 100%;
+  left: 0;
+  position: absolute;
+  top: 0;
+  width: 100%;
+}
+.UnitFixedHeader-overflowSelect {
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  background: transparent;
+  border: 0;
+  color: transparent;
+  cursor: pointer;
+  font-size: 1rem;
+  height: 100%;
+  left: 0;
+  position: absolute;
+  top: 0;
+  width: 100%;
+}
+.UnitFixedHeader-overflowSelect option {
+  color: var(--gray-1);
+}
diff --git a/content/static/html/helpers/_details_fixed_nav.tmpl b/content/static/html/helpers/_unit_fixed_header.tmpl
similarity index 70%
rename from content/static/html/helpers/_details_fixed_nav.tmpl
rename to content/static/html/helpers/_unit_fixed_header.tmpl
index 895956f..dde6b66 100644
--- a/content/static/html/helpers/_details_fixed_nav.tmpl
+++ b/content/static/html/helpers/_unit_fixed_header.tmpl
@@ -4,16 +4,16 @@
   license that can be found in the LICENSE file.
 -->
 
-{{define "details_fixed_nav"}}
-  <div class="DetailsNavFixed js-fixedHeader" aria-hidden="true">
-    <div class="DetailsNavFixed-container">
-      <a href="https://go.dev/" class="DetailsNavFixed-logoLink">
-        <img class="DetailsNavFixed-logo" src="/static/img/go-logo-blue.svg" alt="Go">
+{{define "unit_fixed_header"}}
+  <div class="UnitFixedHeader js-fixedHeader" aria-hidden="true">
+    <div class="UnitFixedHeader-container">
+      <a href="https://go.dev/" class="UnitFixedHeader-logoLink">
+        <img class="UnitFixedHeader-logo" src="/static/img/go-logo-blue.svg" alt="Go">
       </a>
-      <div class="DetailsNavFixed-moduleInfo">
-        <span class="DetailsNavFixed-title">
+      <div class="UnitFixedHeader-moduleInfo">
+        <span class="UnitFixedHeader-title">
           {{if ne .PageType "std"}}
-            <span class="DetailsNavFixed-titleType">
+            <span class="UnitFixedHeader-titleType">
               {{if eq .PageType "mod"}}
                 Module
               {{else if eq .PageType "dir"}}
@@ -24,10 +24,10 @@
                 Command
               {{end}}
             </span>
-            <span class="DetailsNavFixed-titleName">{{.Title}}</span>
+            <span class="UnitFixedHeader-titleName">{{.Title}}</span>
           {{else}}
-            <span class="DetailsNavFixed-titleType">Standard library</span>
-            <span class="DetailsNavFixed-titleType DetailsNavFixed-titleType--small">StdLib</span>
+            <span class="UnitFixedHeader-titleType">Standard library</span>
+            <span class="UnitFixedHeader-titleType UnitFixedHeader-titleType--small">StdLib</span>
           {{end}}
         </span>
         {{with .Breadcrumb}}
@@ -40,9 +40,9 @@
             </button>
           {{end}}
         {{end}}
-        <div class="DetailsNavFixed-version">{{.DisplayVersion}}</div>
+        <div class="UnitFixedHeader-version">{{.DisplayVersion}}</div>
       </div>
-      <div class="DetailsNavFixed-overflowingTabList js-overflowingTabList">
+      <div class="UnitFixedHeader-overflowingTabList js-overflowingTabList">
         <div role="tablist">
           {{range .Tabs}}
             <a role="tab"
@@ -59,12 +59,12 @@
             >{{.DisplayName}}</a>
           {{end}}
         </div>
-        <div class="DetailsNavFixed-overflowContainer">
-          <svg class="DetailsNavFixed-overflowImage" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
+        <div class="UnitFixedHeader-overflowContainer">
+          <svg class="UnitFixedHeader-overflowImage" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
             <path d="M0 0h24v24H0z" fill="none"/>
             <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>
           </svg>
-          <select class="DetailsNavFixed-overflowSelect" aria-label="More">
+          <select class="UnitFixedHeader-overflowSelect" aria-label="More">
             {{range .Tabs}}
               <option
                 value="{{$.CanonicalURLPath}}?tab={{.Name}}"
diff --git a/content/static/html/pages/unit.tmpl b/content/static/html/pages/unit.tmpl
index 3641d6e..e49d48d 100644
--- a/content/static/html/pages/unit.tmpl
+++ b/content/static/html/pages/unit.tmpl
@@ -11,7 +11,7 @@
 {{define "main_content"}}
   <div class="Container">
     {{block "unit_header" .}}{{end}}
-    {{block "details_fixed_nav" .}}{{end}}
+    {{block "unit_fixed_header" .}}{{end}}
     {{block "unit_content" .}}{{end}}
   </div>
 {{end}}
@@ -19,7 +19,7 @@
 {{define "post_content"}}
   <div class="js-canonicalURLPath" data-canonical-url-path="{{.CanonicalURLPath}}" hidden />
   <script>
-    loadScript('/static/js/details.min.js', {async: true, defer: true});
+    loadScript('/static/js/unit_fixed_header.js', {type: 'module', async: true, defer: true})
   </script>
   {{block "unit_post_content" .}}{{end}}
 {{end}}
\ No newline at end of file
diff --git a/content/static/js/unit_fixed_header.js b/content/static/js/unit_fixed_header.js
new file mode 100644
index 0000000..36a19a7
--- /dev/null
+++ b/content/static/js/unit_fixed_header.js
@@ -0,0 +1,73 @@
+/**
+ * @license
+ * Copyright 2019-2020 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+/**
+ * Shows a fixed element when a separate element begins to go out of view.
+ */
+class FixedHeaderController {
+  /**
+   * @param {Element} el
+   * @param {Element} fixedEl
+   */
+  constructor(el, fixedEl) {
+    if (!el || !fixedEl) {
+      throw new Error('Must provide sentinel and fixed elements to constructor.');
+    }
+
+    /**
+     * The element to observe to determine whether to show the fixed element.
+     * @type {!Element}
+     * @private
+     */
+    this._el = /** @type {!Element} */ (el);
+
+    /**
+     * The element to show when the other begins to go out of view.
+     * @type {!Element}
+     * @private
+     */
+    this._fixedEl = /** @type {!Element} */ (fixedEl);
+
+    /**
+     * @type {!IntersectionObserver}
+     * @private
+     */
+    this._intersectionObserver = new IntersectionObserver(
+      (entries, observer) => this.intersectionObserverCallback(entries, observer),
+      {
+        threshold: 1.0,
+      }
+    );
+    this._intersectionObserver.observe(this._el);
+
+    // Fixed positioning on Safari iOS is very broken, and without this hack,
+    // focusing on the overflow menu will cause all content to scroll.
+    // The -webkit-overflow-scroll CSS property is only available on mobile
+    // Safari, so check for it and set the appropriate style to fix this.
+    if (window.getComputedStyle(document.body)['-webkit-overflow-scrolling'] !== undefined) {
+      [document.documentElement, document.body].forEach(el => {
+        el.style.overflow = 'auto';
+      });
+    }
+  }
+
+  /**
+   * @param {!Array<IntersectionObserverEntry>} entries
+   * @param {!IntersectionObserver} observer
+   * @private
+   */
+  intersectionObserverCallback(entries, observer) {
+    entries.forEach(entry => {
+      this._fixedEl.setAttribute('aria-hidden', entry.isIntersecting);
+    });
+  }
+}
+
+new FixedHeaderController(
+  document.querySelector('.js-fixedHeaderSentinel'),
+  document.querySelector('.js-fixedHeader')
+);
diff --git a/internal/middleware/secureheaders.go b/internal/middleware/secureheaders.go
index ae7d278..c8cfaa5 100644
--- a/internal/middleware/secureheaders.go
+++ b/internal/middleware/secureheaders.go
@@ -29,7 +29,7 @@
 	"'sha256-Y1vZzPZ448awUtFwK5f2nES8NyyeM5dgiQ/E3klx4GM='",
 	"'sha256-gBtJYPzfgw/0FIACORDIAD08i5rxTQ5J0rhIU656A2U='",
 	// From content/static/html/pages/unit.tmpl
-	"'sha256-+BVr5T0riD4oQt+Gkp306RbfejUaviIQ9oDKwN4OPak='",
+	"'sha256-RaqfI+f+zdCA5hhJCZgjT75qpniNKKXR7oXUJKsIt14='",
 	// From content/static/html/pages/unit_details.tmpl
 	"'sha256-CFun5NgnYeEpye8qcbQPq5Ycwavi4IXuZiIzSMNqRUw='",
 	"'sha256-IHdniK/yZ8URNA2OYbc4R7BssOAe3/dFrSQW7PxEEfM='",