org.polyfillservice.api.services.PolyfillsOutputService Maven / Gradle / Ivy
The newest version!
package org.polyfillservice.api.services;
import org.polyfillservice.api.components.Feature;
import org.polyfillservice.api.components.Polyfill;
import org.polyfillservice.api.components.Query;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by smo on 4/27/17.
*/
@Service
class PolyfillsOutputService {
private static final String NO_POLYFILLS_MESSAGE = "No polyfills found for current settings";
private static final String MIN_MESSAGE = "Disable minification (remove `.min` from URL path) for more info";
@Resource(name = "projectVersion")
private String projectVersion;
@Resource(name = "projectUrl")
private String projectUrl;
public String getPolyfillsSource(String uaString, Query query, List featuresLoaded) {
String debugInfo = query.isDebugMode() ? getDebugInfo(uaString, query, featuresLoaded): "";
String sources = getSources(featuresLoaded, query.shouldMinify());
String separator = !debugInfo.isEmpty() && !sources.isEmpty() ? "\n\n" : "";
return debugInfo + separator + sources;
}
/**
* Build sources of polyfills
* @return sources of polyfills
*/
private String getSources(List features, boolean minify) {
String sources = features.stream()
.map(feature -> getSource(feature, minify))
.collect(Collectors.joining());
return sources.isEmpty() ? "" : wrapInClosure(sources, minify);
}
/**
* Get source of a feature
* @param feature feature
* @param minify whether to minify source
* @return source of feature
*/
private String getSource(Feature feature, boolean minify) {
Polyfill polyfill = feature.getPolyfill();
String detectSource = polyfill.getDetectSource();
String source = minify ? polyfill.getMinSource() : polyfill.getRawSource();
source = (source == null) ? "" : source;
boolean wrapInDetect = feature.isGated() && detectSource != null;
if (wrapInDetect && !"".equals(detectSource)) {
String lf = minify ? "" : "\n";
return "if(!(" + detectSource + ")){" + lf + source + lf + "}" + lf + lf;
}
return source;
}
/**
* Wrap source in closure to hide private functions
* @return wrapped source
*/
private String wrapInClosure(String source, boolean minify) {
String lf = minify ? "" : "\n";
return "(function(undefined) {" + lf + source + "})" + lf
+ ".call('object' === typeof window && window" // bind `this` to window in a browser
+ " || 'object' === typeof self && self" // bind `this` to self in a web worker
+ " || 'object' === typeof global && global" // bind `this` to global in Node
+ " || {});";
}
/**
* Build header comments for debugging
* @return header comments containing debug info
*/
private String getDebugInfo(String uaString, Query query, List featuresLoaded) {
if (query.shouldMinify()) {
return buildCommentBlock(MIN_MESSAGE);
}
List headers = new ArrayList<>();
headers.add("Polyfill service v" + this.projectVersion);
headers.add("For detailed credits and licence information see " + this.projectUrl);
if (uaString != null) {
headers.add(""); // new line
headers.add("UA detected: " + uaString);
}
if (!query.getFeatures().isEmpty()) {
String featuresRequestedLine = query.getFeatures().stream()
.map(Feature::getName)
.collect(Collectors.joining(","));
headers.add("Features requested: " + featuresRequestedLine);
}
headers.add(""); // new line
if (featuresLoaded.isEmpty()) {
headers.add(NO_POLYFILLS_MESSAGE);
} else {
List featuresLoadedLines = featuresLoaded.stream()
.map(this::formatFeatureLoaded)
.collect(Collectors.toList());
headers.addAll(featuresLoadedLines);
}
return buildCommentBlock(headers);
}
/**
* Wrap lines with comment block
* @return lines wrapped in a comment block
*/
private String buildCommentBlock(List lines) {
return buildCommentBlock(lines.stream().collect(Collectors.joining("\n * ")));
}
private String buildCommentBlock(String line) {
return "/* " + line + " */";
}
/**
* Format feature loaded with license and reverse dependencies
* @param feature feature to format
* @return formatted line with the feature's info
*/
private String formatFeatureLoaded(Feature feature) {
String license = "";
Polyfill polyfill = feature.getPolyfill();
if (polyfill.getLicense() != null) {
license = ", License: " + polyfill.getLicense();
}
String relatedFeatures = "";
if (!feature.getRequiredBys().isEmpty()) {
relatedFeatures = feature.getRequiredBys().stream()
.map(featureName -> "\"" + featureName + "\"")
.collect(Collectors.joining(", "));
relatedFeatures = " (required by " + relatedFeatures + ")";
}
return "- " + feature.getName() + license + relatedFeatures;
}
}