diff --git a/build.sh b/build.sh index d5bade9..66bf894 100755 --- a/build.sh +++ b/build.sh @@ -6,6 +6,12 @@ set -euo pipefail PATH="/tmp/claat:${PATH}" python3 ./build.py sed -e 's#https://storage.googleapis.com/claat-public#/static#g' -i build/*/index.html +# Stop focus() inside an embedding iframe from scrolling the parent page (see static/iframe-focus-fix.js) +sed -e 's##&#' -i build/*/index.html +if grep -L 'iframe-focus-fix.js' build/*/index.html | grep -q .; then + echo "iframe-focus-fix.js was not injected into every page - has claat's script tag changed?" >&2 + exit 1 +fi # The public static hosting seems offline (e.g. https://storage.googleapis.com/claat-public/codelab-elements.css) so we vendor these assets: # Built by running `USE_BAZEL_VERSION=0.19.1 bazel build :bundle` with patches to: diff --git a/static/iframe-focus-fix.js b/static/iframe-focus-fix.js new file mode 100644 index 0000000..7237d37 --- /dev/null +++ b/static/iframe-focus-fix.js @@ -0,0 +1,13 @@ +// When a codelab is embedded in an iframe (e.g. on the CYF curriculum site), +// codelab-elements.js focuses the current step on load. Focusing an element +// inside an iframe scrolls the parent page to the iframe, losing the reader's +// place. Force preventScroll on every focus() call, only when embedded. +// Must load before codelab-elements.js. +(function () { + if (window.self === window.top) return; + var originalFocus = HTMLElement.prototype.focus; + HTMLElement.prototype.focus = function (options) { + var opts = Object.assign({}, options, { preventScroll: true }); + return originalFocus.call(this, opts); + }; +})();