diff --git a/NEWS.cs.md b/NEWS.cs.md
index 6ffba211..54aeeb94 100644
--- a/NEWS.cs.md
+++ b/NEWS.cs.md
@@ -1,3 +1,9 @@
+#### Verze 3.3.0
+
+- Přidána možnost stáhnout anotovaný soubor bez nepotvrzených výskytů.
+- Upraveno fulltextové vyhledávání - nově se zobrazuje informace o atributu, ve kterém byla shoda nalezena.
+- Do fasetového vyhledávání přidána možnost filtrovat dle příkladů (`skos:example`).
+
#### Verze 3.2.0
- Přidána podpora pro import slovníků z MS Excel.
diff --git a/NEWS.en.md b/NEWS.en.md
index 4462c108..d48dc975 100644
--- a/NEWS.en.md
+++ b/NEWS.en.md
@@ -1,3 +1,9 @@
+#### Version 3.3.0
+
+- Added the possibility to download annotated file without unconfirmed occurrences.
+- Enhanced fulltext search - now it shows information about the attribute in which a match was found.
+- Added support for filtering by example (`skos:example`) in the faceted search.
+
#### Version 3.2.0
- Added support for importing a vocabulary from MS Excel.
diff --git a/package-lock.json b/package-lock.json
index 03856ff2..61c6e863 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "termit-ui",
- "version": "3.2.0",
+ "version": "3.3.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "termit-ui",
- "version": "3.2.0",
+ "version": "3.3.1",
"license": "GPL-3.0-only",
"dependencies": {
"@formatjs/intl-pluralrules": "^5.3.1",
@@ -73,7 +73,7 @@
"@redux-devtools/extension": "^3.2.5",
"@types/enzyme": "^3.10.13",
"@types/jest": "^27.4.1",
- "@types/js-cookie": "^3.0.3",
+ "@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.10",
"@types/luxon": "^3.4.2",
"@types/node": "^18.11.17",
@@ -3764,9 +3764,9 @@
}
},
"node_modules/@types/js-cookie": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.3.tgz",
- "integrity": "sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww==",
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
+ "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
"dev": true
},
"node_modules/@types/json-schema": {
@@ -20661,9 +20661,9 @@
}
},
"@types/js-cookie": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.3.tgz",
- "integrity": "sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww==",
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
+ "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
"dev": true
},
"@types/json-schema": {
diff --git a/package.json b/package.json
index 34949c0b..955faa45 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "termit-ui",
- "version": "3.2.0",
+ "version": "3.3.1",
"private": true,
"homepage": ".",
"license": "GPL-3.0-only",
@@ -83,7 +83,7 @@
"@redux-devtools/extension": "^3.2.5",
"@types/enzyme": "^3.10.13",
"@types/jest": "^27.4.1",
- "@types/js-cookie": "^3.0.3",
+ "@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.10",
"@types/luxon": "^3.4.2",
"@types/node": "^18.11.17",
diff --git a/src/component/annotator/AnnotatorContent.tsx b/src/component/annotator/AnnotatorContent.tsx
index 1ec43025..f54a6bbc 100644
--- a/src/component/annotator/AnnotatorContent.tsx
+++ b/src/component/annotator/AnnotatorContent.tsx
@@ -35,8 +35,16 @@ const PREPROCESSING_INSTRUCTIONS = [
shouldPreprocessNode: (node: any): boolean =>
node.name && node.name === "a",
preprocessNode: (node: any) => {
- node.attribs["data-href"] = node.attribs.href;
- delete node.attribs.href;
+ // Remove href from relative links, absolute links will open in blank tab
+ if (!Utils.isLink(node.attribs.href)) {
+ node.attribs["data-href"] = node.attribs.href;
+ delete node.attribs.href;
+ } else {
+ node.attribs["data-target"] = node.attribs.target;
+ node.attribs["target"] = "_blank";
+ node.attribs["data-rel"] = node.attribs.rel;
+ node.attribs["rel"] = "noopener noreferrer";
+ }
},
},
];
diff --git a/src/component/annotator/HtmlParserUtils.ts b/src/component/annotator/HtmlParserUtils.ts
index e0e20842..469d91ef 100644
--- a/src/component/annotator/HtmlParserUtils.ts
+++ b/src/component/annotator/HtmlParserUtils.ts
@@ -4,12 +4,33 @@ import render from "dom-serializer";
const RDF_ATTRIBUTE_NAMES = ["about", "property", "resource", "typeof"];
+function removeAddedAttributes(elem: Element) {
+ // Restore links to their original state - see AnnotatorContent.PREPROCESSING_INSTRUCTIONS
+ if (elem.tagName === "a") {
+ if (elem.attribs["data-href"]) {
+ elem.attribs.href = elem.attribs["data-href"];
+ delete elem.attribs["data-href"];
+ }
+ delete elem.attribs["target"];
+ delete elem.attribs["rel"];
+ if (elem.attribs["data-rel"]) {
+ elem.attribs.rel = elem.attribs["data-rel"];
+ delete elem.attribs["data-rel"];
+ }
+ if (elem.attribs["data-target"]) {
+ elem.attribs.target = elem.attribs["data-target"];
+ delete elem.attribs["data-target"];
+ }
+ }
+}
+
const HtmlParserUtils = {
html2dom(html: string): Node[] {
// Do not decode HTML entities (e.g., <) when parsing content for object representation, it caused issues
// with rendering
const options = { decodeEntities: false };
- const handler = new DomHandler();
+ // @ts-ignore
+ const handler = new DomHandler(null, null, removeAddedAttributes);
const parser = new HtmlParser(handler, options);
parser.parseComplete(html);
return handler.dom as Node[];
diff --git a/src/component/annotator/__tests__/Annotator.test.tsx b/src/component/annotator/__tests__/Annotator.test.tsx
index 31af1e03..99226224 100644
--- a/src/component/annotator/__tests__/Annotator.test.tsx
+++ b/src/component/annotator/__tests__/Annotator.test.tsx
@@ -118,7 +118,7 @@ describe("Annotator", () => {
expect(wrapper.html().includes(sampleContent)).toBe(true);
});
- it("renders body of provided html content with replaced anchor hrefs", () => {
+ it("preserves absolute URL href anchors", () => {
const htmlContent = surroundWithHtml(
'This is a link'
);
@@ -138,7 +138,28 @@ describe("Annotator", () => {
)
);
const sampleOutput =
- 'This is a link';
+ 'This is a link';
+ expect(wrapper.html().includes(sampleOutput)).toBe(true);
+ });
+
+ it("renders body of provided html content with replaced relative anchor hrefs", () => {
+ const htmlContent = surroundWithHtml('This is a link');
+
+ const wrapper = mountWithIntl(
+ withWebSocket(
+
+
+
+ )
+ );
+ const sampleOutput = 'This is a link';
expect(wrapper.html().includes(sampleOutput)).toBe(true);
});
diff --git a/src/component/annotator/__tests__/HtmlParserUtils.test.ts b/src/component/annotator/__tests__/HtmlParserUtils.test.ts
new file mode 100644
index 00000000..620db37f
--- /dev/null
+++ b/src/component/annotator/__tests__/HtmlParserUtils.test.ts
@@ -0,0 +1,22 @@
+import { Element } from "domhandler";
+import HtmlParserUtils from "../HtmlParserUtils";
+
+describe("HtmlParserUtils", () => {
+ describe("html2dom", () => {
+ it("remove target and rel attributes added when rendering HTML", () => {
+ const html =
+ 'Example';
+ const nodes = HtmlParserUtils.html2dom(html);
+ expect((nodes[0] as Element).attribs.href).toEqual("http://example.com");
+ expect((nodes[0] as Element).attribs.target).not.toBeDefined();
+ expect((nodes[0] as Element).attribs.rel).not.toBeDefined();
+ });
+
+ it("set href attribute to data-href attribute created when rendering HTML", () => {
+ const html = 'Example';
+ const nodes = HtmlParserUtils.html2dom(html);
+ expect((nodes[0] as Element).attribs.href).toEqual("./about.html");
+ expect((nodes[0] as Element).attribs["data-href"]).not.toBeDefined();
+ });
+ });
+});
diff --git a/src/util/Utils.ts b/src/util/Utils.ts
index 45b54beb..b4fd2cb9 100644
--- a/src/util/Utils.ts
+++ b/src/util/Utils.ts
@@ -51,10 +51,11 @@ const Utils = {
*/
isLink(str: string): boolean {
return (
- str.startsWith("http://") ||
- str.startsWith("https://") ||
- str.startsWith("ftp://") ||
- str.startsWith("sftp://")
+ str !== undefined &&
+ (str.startsWith("http://") ||
+ str.startsWith("https://") ||
+ str.startsWith("ftp://") ||
+ str.startsWith("sftp://"))
);
},