Skip to content

Commit

Permalink
fix: Check assets for url handling (#10746) (#10755)
Browse files Browse the repository at this point in the history
If a resource is not found in themes folder
check also any assets that are copied for
the theme.

Fixes #10426

Co-authored-by: caalador <mikael.grankvist@vaadin.com>
  • Loading branch information
vaadin-bot and caalador committed Apr 21, 2021
1 parent 493bcb2 commit dabd6f3
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ module.exports = function (source, map) {

source = source.replace(urlMatcher, function (match, url, quoteMark, replace, fileUrl, endString) {
let absolutePath = path.resolve(handledResourceFolder, replace, fileUrl);
if (fs.existsSync(absolutePath) && absolutePath.startsWith(themeFolder)) {
const frontendThemeFolder = "themes/" + path.basename(themeFolder);
if ((fs.existsSync(absolutePath) && absolutePath.startsWith(themeFolder)) || assetsContains(fileUrl, themeFolder, logger)) {
// Adding ./ will skip css-loader, which should be done for asset files
const skipLoader = (fs.existsSync(absolutePath) && absolutePath.startsWith(themeFolder)) ? "": "./";
const frontendThemeFolder = skipLoader + "themes/" + path.basename(themeFolder);
logger.debug("Updating url for file", "'" + replace + fileUrl + "'", "to use", "'" + frontendThemeFolder + "/" + fileUrl + "'");
const pathResolved = absolutePath.substring(themeFolder.length).replace(/\\/g, '/');

Expand All @@ -52,3 +54,46 @@ module.exports = function (source, map) {

this.callback(null, source, map);
}

function assetsContains(fileUrl, themeFolder, logger) {
const themeProperties = getThemeProperties(themeFolder);
if (!themeProperties) {
logger.debug("No theme properties found.");
return false;
}
const assets = themeProperties['assets'];
if (!assets) {
logger.debug("No defined assets in theme properties");
return false;
}
// Go through each asset module
for (let module of Object.keys(assets)) {
const copyRules = assets[module];
// Go through each copy rule
for (let copyRule of Object.keys(copyRules)) {
// if file starts with copyRule target check if file with path after copy target can be found
if (fileUrl.startsWith(copyRules[copyRule])) {
const targetFile = fileUrl.replace(copyRules[copyRule], "");
const files = require('glob').sync(path.resolve('node_modules/', module, copyRule), {nodir: true});

for (let file of files) {
if (file.endsWith(targetFile))
return true;
}
}
}
}
return false;
}

function getThemeProperties(themeFolder) {
const themePropertyFile = path.resolve(themeFolder, 'theme.json');
if (!fs.existsSync(themePropertyFile)) {
return {};
}
const themePropertyFileAsString = fs.readFileSync(themePropertyFile);
if (themePropertyFileAsString.length === 0) {
return {};
}
return JSON.parse(themePropertyFileAsString);
}
6 changes: 6 additions & 0 deletions flow-tests/test-themes/frontend/themes/app-theme/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ body {
display: block;
}

#icon-snowflake {
background-image: url('./fortawesome/icons/snowflake.svg');
height: 1em;
width: 1em;
}

p.global {
color: rgba(255, 255, 0, 1); /* yellow */
font-size: 20px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class ThemeView extends Div {
public static final String FONTAWESOME_ID = "font-awesome";
public static final String SUB_COMPONENT_ID = "sub-component";
public static final String DICE_ID = "dice";
public static final String CSS_SNOWFLAKE = "icon-snowflake";

public ThemeView() {
final Span textSpan = new Span("This is the theme test view");
Expand All @@ -47,6 +48,9 @@ public ThemeView() {
Span octopuss = new Span();
octopuss.setId(OCTOPUSS_ID);

Span cssSnowflake = new Span();
cssSnowflake.setId(CSS_SNOWFLAKE);

Span faText = new Span("This test is FontAwesome.");
faText.setClassName("fas fa-coffee");
faText.setId(FONTAWESOME_ID);
Expand All @@ -61,7 +65,7 @@ public ThemeView() {
"url('themes/app-theme/img/dice.jpg')");
diceImageSpan.setId(DICE_ID);

add(textSpan, snowFlake, subCss, butterfly, octopuss, faText,
add(textSpan, snowFlake, subCss, butterfly, octopuss, cssSnowflake, faText,
diceImageSpan);

add(new Div());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.vaadin.testbench.TestBenchElement;

import static com.vaadin.flow.uitest.ui.theme.ThemeView.BUTTERFLY_ID;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.CSS_SNOWFLAKE;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.DICE_ID;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.FONTAWESOME_ID;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.MY_LIT_ID;
Expand Down Expand Up @@ -70,6 +71,19 @@ public void referenceResourcesOnJavaSideForStyling_stylesAreApplied() {
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
}

@Test
public void nodeAssetInCss_pathIsSetCorrectly() {
open();
final String resourceUrl = getRootURL()
+ "/path/themes/app-theme/fortawesome/icons/snowflake.svg";
WebElement cssNodeSnowflake = findElement(By.id(CSS_SNOWFLAKE));
final String expectedImgUrl = "url(\"" + resourceUrl + "\")";
Assert.assertEquals(
"Background image has been referenced in styles.css and "
+ "expected to be applied",
expectedImgUrl, cssNodeSnowflake.getCssValue("background-image"));
}

@Test
public void secondTheme_staticFilesNotCopied() {
getDriver().get(getRootURL() + "/path/themes/app-theme/img/bg.jpg");
Expand Down

0 comments on commit dabd6f3

Please sign in to comment.