Skip to content

Commit

Permalink
feat(html): Detect deprecated themes in 'href' attributes (#382)
Browse files Browse the repository at this point in the history
JIRA: CPOUI5FOUNDATION-844
  • Loading branch information
maxreichmann authored Oct 24, 2024
1 parent c9a3ab2 commit 2d4bcfa
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 12 deletions.
31 changes: 23 additions & 8 deletions src/linter/html/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,29 @@ import type {ReadStream} from "node:fs";
import {SaxEventType, Tag as SaxTag} from "sax-wasm";
import {parseXML} from "../../utils/xmlParser.js";

export async function extractJSScriptTags(contentStream: ReadStream) {
const scriptTags: SaxTag[] = [];
interface ExtractedTags {
scriptTags: SaxTag[];
stylesheetLinkTags: SaxTag[];
}

export async function extractHTMLTags(contentStream: ReadStream) {
const extractedTags: ExtractedTags = {
scriptTags: [],
stylesheetLinkTags: [],
};
await parseXML(contentStream, (event, tag) => {
if (tag instanceof SaxTag &&
event === SaxEventType.CloseTag &&
if (!(tag instanceof SaxTag)) {
return;
}
if (event === SaxEventType.OpenTag &&
tag.value === "link") {
if (tag.attributes.some((attr) => {
return (attr.name.value === "rel" &&
attr.value.value === "stylesheet");
})) {
extractedTags.stylesheetLinkTags.push(tag);
};
} else if (event === SaxEventType.CloseTag &&
tag.value === "script") {
const isJSScriptTag = tag.attributes.every((attr) => {
// The "type" attribute of the script tag should be
Expand All @@ -23,12 +40,10 @@ export async function extractJSScriptTags(contentStream: ReadStream) {
"application/javascript", /* legacy */
].includes(attr.value.value.toLowerCase()));
});

if (isJSScriptTag) {
scriptTags.push(tag);
extractedTags.scriptTags.push(tag);
}
}
});

return scriptTags;
return extractedTags;
}
20 changes: 16 additions & 4 deletions src/linter/html/transpiler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ReadStream} from "node:fs";
import {extractJSScriptTags} from "./parser.js";
import {extractHTMLTags} from "./parser.js";
import HtmlReporter from "./HtmlReporter.js";
import LinterContext, {ResourcePath, TranspileResult} from "../LinterContext.js";
import {taskStart} from "../../utils/perf.js";
Expand All @@ -13,15 +13,15 @@ export default async function transpileHtml(
try {
const taskEnd = taskStart("Transpile HTML", resourcePath, true);
const report = new HtmlReporter(resourcePath, context);
const jsScriptTags = await extractJSScriptTags(contentStream);
const {scriptTags, stylesheetLinkTags} = await extractHTMLTags(contentStream);

const bootstrapTag = findBootstrapTag(jsScriptTags);
const bootstrapTag = findBootstrapTag(scriptTags);

if (bootstrapTag) {
lintBootstrapAttributes(bootstrapTag, report);
}

jsScriptTags.forEach((tag) => {
scriptTags.forEach((tag) => {
// Tags with src attribute do not parse and run inline code
const hasSrc = tag.attributes.some((attr) => {
return attr.name.value.toLowerCase() === "src";
Expand All @@ -31,6 +31,18 @@ export default async function transpileHtml(
}
});

stylesheetLinkTags.forEach((tag) => {
const href = tag.attributes.find((attr) =>
attr.name.value.toLowerCase() === "href");
if (href) {
deprecatedThemes.forEach((themeName) => {
if (href.value.value.includes(`/themes/${themeName}/`)) {
report.addMessage(MESSAGE.DEPRECATED_THEME, {themeName}, href.value);
}
});
}
});

taskEnd();
return {source: "", map: ""};
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<!-- Relative Path Test Case -->
<link type="text/css" rel="stylesheet" href="../../../resources/sap/ui/core/themes/sap_bluecrystal/library.css">
<link type="text/css" rel="stylesheet" href="../../../resources/sap/m/themes/sap_bluecrystal/library.css">
<link type="text/css" rel="stylesheet" href="../../../resources/sap/m/themes/sap_belize/library.css">
<link
rel="stylesheet"
type="text/css"
crossorigin="anonymous"
href="../../../../../resources/sap/m/themes/sap_belize/library.css"
id="sap-ui-theme-sap.m"/>
<!-- Absolute Path Test Case-->
<link type="text/css" rel="stylesheet" href="/resources/sap/m/themes/sap_belize/library.css">
<!-- Negative Test Cases (no deprecation) -->
<link type="text/css" rel="stylesheet" href="/resources/sap/m/themes/sap_horizon/library.css">
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body class="sapUiBody">
</body>
</html>
56 changes: 56 additions & 0 deletions test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,62 @@ Generated by [AVA](https://avajs.dev).
},
]

## General: DeprecatedThemeLinkTags.html

> Snapshot 1
[
{
coverageInfo: [],
errorCount: 5,
fatalErrorCount: 0,
filePath: 'DeprecatedThemeLinkTags.html',
messages: [
{
column: 48,
line: 5,
message: 'Use of deprecated theme \'sap_bluecrystal\'',
messageDetails: 'Deprecated Themes and Libraries (https://ui5.sap.com/#/topic/a87ca843bcee469f82a9072927a7dcdb)',
ruleId: 'no-deprecated-theme',
severity: 2,
},
{
column: 48,
line: 6,
message: 'Use of deprecated theme \'sap_bluecrystal\'',
messageDetails: 'Deprecated Themes and Libraries (https://ui5.sap.com/#/topic/a87ca843bcee469f82a9072927a7dcdb)',
ruleId: 'no-deprecated-theme',
severity: 2,
},
{
column: 48,
line: 7,
message: 'Use of deprecated theme \'sap_belize\'',
messageDetails: 'Deprecated Themes and Libraries (https://ui5.sap.com/#/topic/a87ca843bcee469f82a9072927a7dcdb)',
ruleId: 'no-deprecated-theme',
severity: 2,
},
{
column: 10,
line: 12,
message: 'Use of deprecated theme \'sap_belize\'',
messageDetails: 'Deprecated Themes and Libraries (https://ui5.sap.com/#/topic/a87ca843bcee469f82a9072927a7dcdb)',
ruleId: 'no-deprecated-theme',
severity: 2,
},
{
column: 48,
line: 15,
message: 'Use of deprecated theme \'sap_belize\'',
messageDetails: 'Deprecated Themes and Libraries (https://ui5.sap.com/#/topic/a87ca843bcee469f82a9072927a7dcdb)',
ruleId: 'no-deprecated-theme',
severity: 2,
},
],
warningCount: 0,
},
]

## General: ManagedObject.js

> Snapshot 1
Expand Down
Binary file modified test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap
Binary file not shown.

0 comments on commit 2d4bcfa

Please sign in to comment.