mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 12:07:51 +02:00
138 lines
5.4 KiB
Java
138 lines
5.4 KiB
Java
// Copyright 2016 The Nomulus Authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package google.registry.ui.server;
|
|
|
|
import static com.google.common.base.MoreObjects.firstNonNull;
|
|
import static com.google.common.base.Suppliers.memoize;
|
|
import static com.google.common.io.Resources.asCharSource;
|
|
import static com.google.common.io.Resources.getResource;
|
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
|
|
import com.google.common.base.Joiner;
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.base.Supplier;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.io.Resources;
|
|
import com.google.re2j.Matcher;
|
|
import com.google.re2j.Pattern;
|
|
import com.google.template.soy.SoyFileSet;
|
|
import com.google.template.soy.SoyUtils;
|
|
import com.google.template.soy.base.SoySyntaxException;
|
|
import com.google.template.soy.parseinfo.SoyFileInfo;
|
|
import com.google.template.soy.shared.SoyCssRenamingMap;
|
|
import com.google.template.soy.tofu.SoyTofu;
|
|
import google.registry.ui.ConsoleDebug;
|
|
import java.io.IOException;
|
|
import java.net.URL;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/** Helper methods for rendering Soy templates from Java code. */
|
|
public final class SoyTemplateUtils {
|
|
|
|
/** Returns a memoized supplier containing compiled tofu. */
|
|
public static Supplier<SoyTofu> createTofuSupplier(final SoyFileInfo... soyInfos) {
|
|
return memoize(new Supplier<SoyTofu>() {
|
|
@Override
|
|
public SoyTofu get() {
|
|
ConsoleDebug debugMode = ConsoleDebug.get();
|
|
SoyFileSet.Builder builder = SoyFileSet.builder();
|
|
for (SoyFileInfo soyInfo : soyInfos) {
|
|
builder.add(getResource(soyInfo.getClass(), soyInfo.getFileName()));
|
|
}
|
|
Map<String, Object> globals = new HashMap<>();
|
|
try {
|
|
globals.putAll(SoyUtils.parseCompileTimeGlobals(asCharSource(SOY_GLOBALS, UTF_8)));
|
|
} catch (SoySyntaxException | IOException e) {
|
|
throw new RuntimeException("Failed to load soy globals", e);
|
|
}
|
|
globals.put("DEBUG", debugMode.ordinal());
|
|
builder.setCompileTimeGlobals(globals);
|
|
return builder.build().compileToTofu();
|
|
}});
|
|
}
|
|
|
|
/** Returns a memoized supplier of the thing you pass to {@code setCssRenamingMap()}. */
|
|
public static Supplier<SoyCssRenamingMap> createCssRenamingMapSupplier(
|
|
final URL cssMap,
|
|
final URL cssMapDebug) {
|
|
return memoize(new Supplier<SoyCssRenamingMap>() {
|
|
@Override
|
|
public SoyCssRenamingMap get() {
|
|
final ImmutableMap<String, String> renames = getCssRenames(cssMap, cssMapDebug);
|
|
return new SoyCssRenamingMap() {
|
|
@Override
|
|
public String get(String cssClassName) {
|
|
List<String> result = new ArrayList<>();
|
|
for (String part : CSS_CLASS_SPLITTER.split(cssClassName)) {
|
|
result.add(firstNonNull(renames.get(part), part));
|
|
}
|
|
return CSS_CLASS_JOINER.join(result);
|
|
}};
|
|
}});
|
|
}
|
|
|
|
private static ImmutableMap<String, String> getCssRenames(URL cssMap, URL cssMapDebug) {
|
|
try {
|
|
switch (ConsoleDebug.get()) {
|
|
case RAW:
|
|
return ImmutableMap.of(); // See firstNonNull() above for clarification.
|
|
case DEBUG:
|
|
return extractCssRenames(Resources.toString(cssMapDebug, UTF_8));
|
|
default:
|
|
return extractCssRenames(Resources.toString(cssMap, UTF_8));
|
|
}
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("Failed to load css map", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extract class name rewrites from a {@code .css.js} mapping file.
|
|
*
|
|
* <p>This is the file created when you pass {@code --css_renaming_output_file} to the Closure
|
|
* Stylesheets compiler. In order for this to work, {@code --output_renaming_map_format} should
|
|
* be {@code CLOSURE_COMPILED} or {@code CLOSURE_UNCOMPILED}.
|
|
*
|
|
* <p>Here's an example of what the {@code .css.js} file looks like:<pre>
|
|
*
|
|
* goog.setCssNameMapping({
|
|
* "nonLatin": "a",
|
|
* "secondary": "b",
|
|
* "mobile": "c"
|
|
* });</pre>
|
|
*
|
|
* <p>This is a burden that's only necessary for tofu, since the closure compiler is smart enough
|
|
* to substitute CSS class names when soy is compiled to JavaScript.
|
|
*/
|
|
private static ImmutableMap<String, String> extractCssRenames(String json) {
|
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
|
|
Matcher matcher = KEY_VALUE_PATTERN.matcher(json);
|
|
while (matcher.find()) {
|
|
builder.put(matcher.group(1), matcher.group(2));
|
|
}
|
|
return builder.build();
|
|
}
|
|
|
|
private static final URL SOY_GLOBALS = getResource("google/registry/ui/globals.txt");
|
|
private static final Splitter CSS_CLASS_SPLITTER = Splitter.on('-');
|
|
private static final Joiner CSS_CLASS_JOINER = Joiner.on('-');
|
|
private static final Pattern KEY_VALUE_PATTERN =
|
|
Pattern.compile("['\"]([^'\"]+)['\"]: ['\"]([^'\"]+)['\"]");
|
|
|
|
private SoyTemplateUtils() {}
|
|
}
|