Merge remote-tracking branch 'upstream/master'
# Conflicts:
# tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
index 30918b2..664b3b8 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TabGroupRenderer.java
@@ -149,12 +149,11 @@
final Markup markup = tabGroup.getMarkup();
final TobagoResponseWriter writer = getResponseWriter(facesContext);
- writer.startElement(HtmlElements.DIV);
+ writer.startElement(HtmlElements.TOBAGO_TAB_GROUP);
writer.writeIdAttribute(clientId);
writer.writeClassAttribute(
- TobagoClass.TAB_GROUP,
- TobagoClass.TAB_GROUP.createMarkup(markup),
BootstrapClass.CARD,
+ TobagoClass.TAB_GROUP.createMarkup(markup),
tabGroup.getCustomClass(),
markup != null && markup.contains(Markup.SPREAD) ? TobagoClass.SPREAD : null);
HtmlRendererUtils.writeDataAttributes(facesContext, writer, tabGroup);
@@ -173,7 +172,7 @@
encodeContent(facesContext, writer, tabGroup, activeIndex, switchType);
- writer.endElement(HtmlElements.DIV);
+ writer.endElement(HtmlElements.TOBAGO_TAB_GROUP);
}
private int ensureRenderedActiveIndex(final FacesContext context, final AbstractUITabGroup tabGroup) {
@@ -217,6 +216,8 @@
final int activeIndex, final SwitchType switchType)
throws IOException {
+ final String tabGroupClientId = tabGroup.getClientId(facesContext);
+
writer.startElement(HtmlElements.DIV);
writer.writeClassAttribute(BootstrapClass.CARD_HEADER);
writer.startElement(HtmlElements.UL);
@@ -249,7 +250,7 @@
markup = markup.add(ComponentUtils.markupOfSeverity(maxSeverity));
}
- writer.startElement(HtmlElements.LI);
+ writer.startElement(HtmlElements.TOBAGO_TAB);
writer.writeIdAttribute(tabId);
writer.writeClassAttribute(
TobagoClass.TAB,
@@ -257,6 +258,7 @@
BootstrapClass.NAV_ITEM,
barFacet != null ? TobagoClass.TAB__BAR_FACET : null,
tab.getCustomClass());
+ writer.writeAttribute(HtmlAttributes.FOR, tabGroupClientId, true);
writer.writeAttribute(HtmlAttributes.ROLE, HtmlRoleValues.PRESENTATION.toString(), false);
writer.writeAttribute(DataAttributes.TAB_GROUP_INDEX, index);
final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, tab);
@@ -322,7 +324,7 @@
writer.endElement(HtmlElements.DIV);
}
- writer.endElement(HtmlElements.LI);
+ writer.endElement(HtmlElements.TOBAGO_TAB);
}
index++;
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
index 8766a3d..b84f6e1 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
@@ -138,7 +138,9 @@
TOBAGO_POPUP("tobago-popup"),
TOBAGO_SPLIT_LAYOUT("tobago-split-layout"),
TOBAGO_STARS("tobago-stars"),
- TOBAGO_SUGGEST("tobago-suggest");
+ TOBAGO_SUGGEST("tobago-suggest"),
+ TOBAGO_TAB("tobago-tab"),
+ TOBAGO_TAB_GROUP("tobago-tab-group");
private final String value;
private final boolean voidElement;
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts
index b66d8c4..d54e0bd 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-command.ts
@@ -244,46 +244,54 @@
}
static init = function (element: HTMLElement) {
+ Command.initialize(element, false);
+ };
+
+ static initialize = function (element: HTMLElement, force: boolean) {
for (const commandElement of DomUtils.selfOrQuerySelectorAll(element, "[data-tobago-commands]")) {
- const commandMap = new CommandMap(commandElement.dataset["tobagoCommands"]);
+ // TODO hack to set command eventListeners after tobago-tab EventListeners
+ if (force || commandElement.parentElement.tagName !== "TOBAGO-TAB") {
- for (const entry of commandMap.commands.entries()) {
- const key: string = entry[0];
- const value: Command = entry[1];
+ const commandMap = new CommandMap(commandElement.dataset["tobagoCommands"]);
- switch(key) {
- case "change":
- commandElement.addEventListener("change", CommandMap.change);
- break;
- case "complete":
- if (parseFloat(commandElement.getAttribute("value")) >= parseFloat(commandElement.getAttribute("max"))) {
- if (commandMap.complete.execute || commandMap.complete.render) {
- jsf.ajax.request(
- this.id,
- null,
- {
- "javax.faces.behavior.event": "complete",
- execute: commandMap.complete.execute,
- render: commandMap.complete.render
- });
- } else {
- Command.submitAction(this, commandMap.complete.action, commandMap.complete);
+ for (const entry of commandMap.commands.entries()) {
+ const key: string = entry[0];
+ const value: Command = entry[1];
+
+ switch (key) {
+ case "change":
+ commandElement.addEventListener("change", CommandMap.change);
+ break;
+ case "complete":
+ if (parseFloat(commandElement.getAttribute("value")) >= parseFloat(commandElement.getAttribute("max"))) {
+ if (commandMap.complete.execute || commandMap.complete.render) {
+ jsf.ajax.request(
+ this.id,
+ null,
+ {
+ "javax.faces.behavior.event": "complete",
+ execute: commandMap.complete.execute,
+ render: commandMap.complete.render
+ });
+ } else {
+ Command.submitAction(this, commandMap.complete.action, commandMap.complete);
+ }
}
- }
- break;
- case "load":
- setTimeout(function () {
- Command.submitAction(this, commandMap.load.action, commandMap.load);
- },
- commandMap.load.delay || 100);
- break;
- case "resize":
- window.addEventListener("resize", CommandMap.resize);
- break;
- default:
- commandElement.addEventListener(key, CommandMap.otherEvent);
+ break;
+ case "load":
+ setTimeout(function () {
+ Command.submitAction(this, commandMap.load.action, commandMap.load);
+ },
+ commandMap.load.delay || 100);
+ break;
+ case "resize":
+ window.addEventListener("resize", CommandMap.resize);
+ break;
+ default:
+ commandElement.addEventListener(key, CommandMap.otherEvent);
+ }
}
}
}
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts
index a422bae..eabfdcc 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/ts/tobago-tab.ts
@@ -15,75 +15,77 @@
* limitations under the License.
*/
-import {Listener, Phase} from "./tobago-listener";
-import {DomUtils} from "./tobago-utils";
+import {Command} from "./tobago-command";
-/**
- * Initializes the tab-groups.
- * @param element
- */
-class TabGroup {
- static init = function (element: HTMLElement) {
+class TabGroup extends HTMLElement {
+ private markupCssClass: string = "tobago-tab-markup-selected";
- const markupString = "selected";
- const markupCssClass = "tobago-tab-markup-selected";
+ constructor() {
+ super();
+ }
- for (const e of DomUtils.selfOrQuerySelectorAll(element, ".tobago-tabGroup")) {
- const tabGroup: HTMLDivElement = e as HTMLDivElement;
- const hiddenInput: HTMLInputElement = TabGroup.getHiddenInput(tabGroup);
- const tabs: NodeListOf<HTMLLIElement> = TabGroup.getTabs(tabGroup);
+ connectedCallback() {
+ const tabGroup: TabGroup = this;
+ const hiddenInput: HTMLInputElement = this.querySelector(":scope > input[type=hidden]");
- for (const tab of tabs) {
- const navLink: HTMLLinkElement = tab.querySelector(":scope > .nav-link");
- if (!navLink.classList.contains("disabled")) {
- navLink.addEventListener('click', function () {
- const tabGroupIndex: string = tab.dataset.tobagoTabGroupIndex;
- hiddenInput.value = tabGroupIndex;
+ for (const tab of tabGroup.tabs) {
+ const navLink: HTMLLinkElement = tab.querySelector(":scope > .nav-link");
+ if (!navLink.classList.contains("disabled")) {
+ navLink.addEventListener('click', function () {
+ hiddenInput.value = tab.groupIndex;
- if (tabGroup.dataset.tobagoSwitchType === "client") {
- const activeTab: HTMLLIElement = TabGroup.getActiveTab(tabGroup);
- const activeNavLink: HTMLLinkElement = TabGroup.getActiveNavLink(tabGroup);
- const activeTabContent: HTMLDivElement = TabGroup.getActiveTabContent(tabGroup);
+ if (tabGroup.dataset.tobagoSwitchType === "client") {
+ tabGroup.activeTab.classList.remove(tabGroup.markupCssClass);
+ tabGroup.activeNavLink.classList.remove("active");
+ tabGroup.activeTabContent.classList.remove("active");
- activeTab.classList.remove(markupCssClass);
- activeNavLink.classList.remove("active");
- activeTabContent.classList.remove("active");
-
- tab.classList.add(markupCssClass);
- navLink.classList.add("active");
- TabGroup.getTabContent(tabGroup, tabGroupIndex).classList.add("active");
- }
- });
- }
+ tab.classList.add(tabGroup.markupCssClass);
+ navLink.classList.add("active");
+ tabGroup.getTabContent(tab.groupIndex).classList.add("active");
+ }
+ });
}
}
- };
- static getHiddenInput(tabGroup: HTMLDivElement): HTMLInputElement {
- return tabGroup.querySelector(":scope > input[type=hidden]");
+ Command.initialize(tabGroup, true);
}
- static getTabs(tabGroup: HTMLDivElement): NodeListOf<HTMLLIElement> {
- return tabGroup.querySelectorAll(":scope > .card-header > .tobago-tabGroup-header > .tobago-tab");
+ get tabs(): NodeListOf<Tab> {
+ return this.querySelectorAll("tobago-tab[for='" + this.id + "']");
}
- static getActiveTab(tabGroup: HTMLDivElement): HTMLLIElement {
- return this.getActiveNavLink(tabGroup).parentElement as HTMLLIElement;
+ get activeTab(): Tab {
+ return this.querySelector("tobago-tab[for='" + this.id + "']." + this.markupCssClass);
}
- static getActiveNavLink(tabGroup: HTMLDivElement): HTMLLinkElement {
- return tabGroup.querySelector(":scope > .card-header > .tobago-tabGroup-header > .tobago-tab > .nav-link.active");
+ get activeNavLink(): HTMLLinkElement {
+ return this.querySelector("tobago-tab[for='" + this.id + "'] > .nav-link.active");
}
- static getActiveTabContent(tabGroup: HTMLDivElement): HTMLDivElement {
- return tabGroup.querySelector(":scope > .card-body.tab-content > .tobago-tab-content.active");
+ get activeTabContent(): HTMLDivElement {
+ return this.querySelector(":scope > .card-body.tab-content > .tobago-tab-content.active");
}
- static getTabContent(tabGroup: HTMLDivElement, tabGroupIndex: string): HTMLDivElement {
- return tabGroup.querySelector(":scope > .card-body > .tobago-tab-content[data-tobago-tab-group-index='"
+ getTabContent(tabGroupIndex: string): HTMLDivElement {
+ return this.querySelector(":scope > .card-body > .tobago-tab-content[data-tobago-tab-group-index='"
+ tabGroupIndex + "']");
}
}
-Listener.register(TabGroup.init, Phase.DOCUMENT_READY);
-Listener.register(TabGroup.init, Phase.AFTER_UPDATE);
+class Tab extends HTMLElement {
+ constructor() {
+ super();
+ }
+
+ connectedCallback() {
+ }
+
+ get groupIndex(): string {
+ return this.dataset.tobagoTabGroupIndex;
+ }
+}
+
+document.addEventListener("DOMContentLoaded", function (event) {
+ window.customElements.define('tobago-tab-group', TabGroup);
+ // window.customElements.define('tobago-tab', Tab);
+});