private static void setupFrameworkLibraries(Element head, JsonObject initialUIDL, BootstrapContext context) { inlineEs6Collections(head, context); appendWebComponentsPolyfills(head, context); if (context.getPushMode().isEnabled()) { head.appendChild(getPushScript(context)); } head.appendChild(getBootstrapScript(initialUIDL, context)); head.appendChild(createJavaScriptElement(getClientEngineUrl(context))); }
private static List<Element> setupDocumentHead(Element head, BootstrapContext context) { setupMetaAndTitle(head, context); setupCss(head, context); JsonObject initialUIDL = getInitialUidl(context.getUI()); Map<LoadMode, JsonArray> dependenciesToProcessOnServer = popDependenciesToProcessOnServer( initialUIDL); setupFrameworkLibraries(head, initialUIDL, context); return applyUserDependencies(head, context, dependenciesToProcessOnServer); }
@Override public boolean synchronizedHandleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { // Find UI class Class<? extends UI> uiClass = getUIClass(request); BootstrapContext context = createAndInitUI(uiClass, request, response, session); ServletHelper.setResponseNoCacheHeaders(response::setHeader, response::setDateHeader); Document document = getBootstrapPage(context); writeBootstrapPage(response, document.outerHtml()); return true; }
private static Element getBootstrapScript(JsonValue initialUIDL, BootstrapContext context) { return createInlineJavaScriptElement("//<![CDATA[\n" + getBootstrapJS(initialUIDL, context) + "//]]>"); }
html.appendElement("body"); List<Element> dependenciesToInlineInBody = setupDocumentHead(head, context); dependenciesToInlineInBody .forEach(dependency -> document.body().appendChild(dependency)); setupDocumentBody(document); .ifPresent(targets -> handleInlineTargets(context, head, document.body(), targets)); initialPageSettings -> handleInitialPageSettings(context, head, initialPageSettings)); handleThemeContents(context, document); exportUsageStatistics(document); setupPwa(document, context);
private static void handleInlineTargets(BootstrapContext context, Element head, Element body, InlineTargets targets) { targets.getInlineHead(Inline.Position.PREPEND).stream() .map(dependency -> createDependencyElement(context, dependency)) .forEach( element -> insertElements(element, head::prependChild)); targets.getInlineHead(Inline.Position.APPEND).stream() .map(dependency -> createDependencyElement(context, dependency)) .forEach(element -> insertElements(element, head::appendChild)); targets.getInlineBody(Inline.Position.PREPEND).stream() .map(dependency -> createDependencyElement(context, dependency)) .forEach( element -> insertElements(element, body::prependChild)); targets.getInlineBody(Inline.Position.APPEND).stream() .map(dependency -> createDependencyElement(context, dependency)) .forEach(element -> insertElements(element, body::appendChild)); }
private static Element createDependencyElement( BootstrapUriResolver resolver, LoadMode loadMode, JsonObject dependency, Dependency.Type type) { boolean inlineElement = loadMode == LoadMode.INLINE; String url = dependency.hasKey(Dependency.KEY_URL) ? resolver.resolveVaadinUri( dependency.getString(Dependency.KEY_URL)) : null; final Element dependencyElement; switch (type) { case STYLESHEET: dependencyElement = createStylesheetElement(url); break; case JAVASCRIPT: dependencyElement = createJavaScriptElement(url, !inlineElement); break; case HTML_IMPORT: dependencyElement = createHtmlImportElement(url); break; default: throw new IllegalStateException( "Unsupported dependency type: " + type); } if (inlineElement) { dependencyElement.appendChild( new DataNode(dependency.getString(Dependency.KEY_CONTENTS), dependencyElement.baseUri())); } return dependencyElement; }
head.appendChild(createInlineJavaScriptElement(BABEL_HELPERS_JS)); createJavaScriptElement(context.getUriResolver() .resolveVaadinUri(es5AdapterUrl), false)); head.appendChild(createJavaScriptElement(resolvedUrl, false));
private static Element createJavaScriptElement(String sourceUrl) { return createJavaScriptElement(sourceUrl, true); }
private static List<Element> inlineDependenciesInHead(Element head, BootstrapUriResolver uriResolver, LoadMode loadMode, JsonArray dependencies) { List<Element> dependenciesToInlineInBody = new ArrayList<>(); for (int i = 0; i < dependencies.length(); i++) { JsonObject dependencyJson = dependencies.getObject(i); Dependency.Type dependencyType = Dependency.Type .valueOf(dependencyJson.getString(Dependency.KEY_TYPE)); Element dependencyElement = createDependencyElement(uriResolver, loadMode, dependencyJson, dependencyType); if (loadMode == LoadMode.INLINE && dependencyType == Dependency.Type.HTML_IMPORT) { dependenciesToInlineInBody.add(dependencyElement); } else { head.appendChild(dependencyElement); } } return dependenciesToInlineInBody; }
@Override protected List<RequestHandler> createRequestHandlers() throws ServiceException { List<RequestHandler> handlers = super.createRequestHandlers(); handlers.add(0, new FaviconHandler()); handlers.add(0, new BootstrapHandler()); if (isAtmosphereAvailable()) { try { handlers.add(new PushRequestHandler(this)); } catch (ServiceException e) { // Atmosphere init failed. Push won't work but we don't throw a // service exception as we don't want to prevent non-push // applications from working getLogger().warn( "Error initializing Atmosphere. Push will not work.", e); } } return handlers; }
private static void inlineEs6Collections(Element head, BootstrapContext context) { if (!context.getSession().getBrowser().isEs6Supported()) { head.appendChild(createInlineJavaScriptElement(ES6_COLLECTIONS)); } }
private static void handleInitialPageSettings(BootstrapContext context, Element head, InitialPageSettings initialPageSettings) { if (initialPageSettings.getViewport() != null) { Elements viewport = head.getElementsByAttributeValue("name", VIEWPORT); if (!viewport.isEmpty() && viewport.size() == 1) { viewport.get(0).attr(CONTENT_ATTRIBUTE, initialPageSettings.getViewport()); } else { head.appendElement(META_TAG).attr("name", VIEWPORT).attr( CONTENT_ATTRIBUTE, initialPageSettings.getViewport()); } } initialPageSettings.getInline(InitialPageSettings.Position.PREPEND) .stream() .map(dependency -> createDependencyElement(context, dependency)) .forEach( element -> insertElements(element, head::prependChild)); initialPageSettings.getInline(InitialPageSettings.Position.APPEND) .stream() .map(dependency -> createDependencyElement(context, dependency)) .forEach(element -> insertElements(element, head::appendChild)); initialPageSettings.getElement(InitialPageSettings.Position.PREPEND) .forEach( element -> insertElements(element, head::prependChild)); initialPageSettings.getElement(InitialPageSettings.Position.APPEND) .forEach(element -> insertElements(element, head::appendChild)); }
private static Element createInlineJavaScriptElement( String javaScriptContents) { // defer makes no sense without src: // https://developer.mozilla.org/en/docs/Web/HTML/Element/script Element wrapper = createJavaScriptElement(null, false); wrapper.appendChild( new DataNode(javaScriptContents, wrapper.baseUri())); return wrapper; }
private static Element createDependencyElement(BootstrapContext context, JsonObject dependencyJson) { String type = dependencyJson.getString(Dependency.KEY_TYPE); if (Dependency.Type.contains(type)) { Dependency.Type dependencyType = Dependency.Type.valueOf(type); return createDependencyElement(context.getUriResolver(), LoadMode.INLINE, dependencyJson, dependencyType); } return Jsoup.parse(dependencyJson.getString(Dependency.KEY_CONTENTS), "", Parser.xmlParser()); }
private static void handleThemeContents(BootstrapContext context, Document document) { ThemeSettings themeSettings = BootstrapUtils.getThemeSettings(context); if (themeSettings == null) { // no theme configured for the application return; } List<JsonObject> themeContents = themeSettings.getHeadContents(); if (themeContents != null) { themeContents.stream().map( dependency -> createDependencyElement(context, dependency)) .forEach(element -> insertElements(element, document.head()::appendChild)); } JsonObject themeContent = themeSettings.getHeadInjectedContent(); if (themeContent != null) { Element dependency = createDependencyElement(context, themeContent); insertElements(dependency, document.head()::appendChild); } if (themeSettings.getBodyAttributes() != null) { themeSettings.getBodyAttributes() .forEach((key, value) -> document.body().attr(key, value)); } }
private static Element getPushScript(BootstrapContext context) { VaadinRequest request = context.getRequest(); // Parameter appended to JS to bypass caches after version upgrade. String versionQueryParam = "?v=" + Version.getFullVersion(); // Load client-side dependencies for push support String pushJSPath = ServletHelper.getContextRootRelativePath(request) + "/"; if (request.getService().getDeploymentConfiguration() .isProductionMode()) { pushJSPath += ApplicationConstants.VAADIN_PUSH_JS; } else { pushJSPath += ApplicationConstants.VAADIN_PUSH_DEBUG_JS; } pushJSPath += versionQueryParam; return createJavaScriptElement(pushJSPath); }