/// interface JQuery { asTabWidget(copy?: boolean) : JQuery; tabify(copy?: boolean) : this; changeElementType(type: string) : JQuery; } if(typeof (customElements) !== "undefined") { try { class X_Tab extends HTMLElement {} class X_Entry extends HTMLElement {} class X_Tag extends HTMLElement {} class X_Content extends HTMLElement {} customElements.define('x-tab', X_Tab, { extends: 'div' }); customElements.define('x-entry', X_Entry, { extends: 'div' }); customElements.define('x-tag', X_Tag, { extends: 'div' }); customElements.define('x-content', X_Content, { extends: 'div' }); } catch(error) { console.warn("failed to define costum elements"); } } else { console.warn(tr("Could not defied tab customElements!")); } var TabFunctions = { tabify(template: JQuery, copy: boolean = true) : JQuery { console.log("Tabify: copy=" + copy); console.log(template); let tag = $.spawn("div"); tag.addClass("tab"); let header = $.spawn("div"); header.addClass("tab-header"); let content = $.spawn("div"); content.addClass("tab-content"); content.append($.spawn("div").addClass("height-watcher")); let silentContent = $.spawn("div"); silentContent.addClass("tab-content-invisible"); /* add some kind of min height */ const update_height = () => { const height_watcher = tag.find("> .tab-content .height-watcher"); const entries: JQuery = tag.find("> .tab-content-invisible x-content, > .tab-content x-content"); console.error(entries); let max_height = 0; entries.each((_, _e) => { const entry = $(_e); const height = entry.visible_height(); if(height > max_height) max_height = height; }); height_watcher.css('min-height', max_height + "px"); }; template.find("x-entry").each( (_, _entry) => { const entry = $(_entry); let tag_header = $.spawn("div").addClass("entry"); if(copy) tag_header.append(entry.find("x-tag").clone(true, true)); else tag_header.append(entry.find("x-tag")); const tag_content = copy ? entry.find("x-content").clone(true, true) : entry.find("x-content"); content.append(tag_content.hide()); tag_header.on("click", () => { if(tag_header.hasClass("selected")) return; tag.find(".tab-header .selected").removeClass("selected"); tag_header.addClass("selected"); content.find("> x-content").hide(); /* don't show many nodes at once */ let entries = tag_content.find(".tab-show-partitional"); entries.hide(); const show_next = index => { console.log("Show " + index); if(index >= entries.length) return; entries.eq(index).show(); setTimeout(show_next.bind(undefined, index + 1), 0); }; show_next(0); tag_content.trigger('show'); tag_content.show(); }); console.log(this); header.append(tag_header); }); setTimeout(() => header.find(".entry").first().trigger("click"), 0); tag.append(header); tag.append(content); tag.append(silentContent); tag.on('tab.resize', update_height); return tag; } } if(!$.fn.asTabWidget) { $.fn.asTabWidget = function (copy?: boolean) : JQuery { if($(this).prop("tagName") == "X-TAB") return TabFunctions.tabify($(this), typeof(copy) === "boolean" ? copy : true); else { throw "Invalid tag! " + $(this).prop("tagName"); } } } if(!$.fn.tabify) { $.fn.tabify = function (this: JQuery, copy?: boolean) { const wrapped_tag = $.spawn("div").append(this); wrapped_tag.find("x-tab").each((_, _element) => { const element = $(_element); element.replaceWith(element.asTabWidget(copy)); }); return wrapped_tag.children(); } }