Dies führt aber dazu, dass Standardknöpfe, wie Seiteneinstellungen, auf der Seite mit diesem HTML Macro nicht mehr funktionieren.
Ich habe zwar Limiting scope of JavaScript source gefunden aber wenn dies die Lösung sein soll, habe wir es bei uns noch nicht zum laufen gebracht .
leider schafft das keiner von unseren Experten “kurz mal” zu beantworten. Das müsste sich nämlich wohl jemand mit Frontent-Skills anschauen und dazu hat momentan niemand Kapazitäten frei . Ich hoffe, du verstehst das.
Aber vielleicht meldet sich ja hier noch jemand, der weiterhelfen kann, schauen wir mal!
Vielleicht kannst Du mal beschreiben, warum Du das eigentlich genau machen willst? Soll das ein Theme mit Layout-Anpassungen werden? Oder wofür wird das gebraucht? Ohne Kontext kann ich zumindest nichts Schlaues sagen. Sorry.
Ja und mehr. Das Grundproblem ist, dass unsere Firma nicht die kleinste ist und Erweiterung der Funktionalität, welche mit Kosten verbunden ist, ein langer und nicht immer erfolgsversprechend. Glücklicherweise wurde vor kurzem das HTML Macro mit vollem Funktionsumfang freigeschaltet, sprich JavaScript ist auch zugelassen.
Somit habe ich angefangen zu experimentieren, was möglich ist, um einfach und auch komplexere Funktionen zu integrieren und Wert einer Seite massiv zu erhöhen.
Dabei bin ich auf viele nützliche öffentliche JavaScript Bibliotheken gestossen, die für mich hilfreich sind. Nun bin ich bei Bootstrap gelandet und möchte es in meinem HTML Macro einsetzten aber ohne die beschriebenen Auswirkungen auf den Rest der Seite, sprich was Confluence per se mitliefert.
Es ist mir erst bei Bootstrap aufgefallen aber ich denke andere Skripte können die gleichen Auswirkungen haben, von daher mein Verweis auf Bootstrap. Die Frage zielt eher darauf ab, dass von aussen eingebundene Skripte nur innerhalb des Inhaltes des HTML Macro Gültigkeit haben, bzw. berücksichtigt werden vom Browser.
@mseibert, konnte ich damit deine Frage damit beantworten?
Ich bin kein ausgemachter Entwickler. Unsere Mitarbeitenden wissen, dass ich eher das Gegenteil bin. Insofern ist das Folgende mit Vorsicht zu genießen:
Der über das HTML-Makro eingebrachte Code wird ganz normal im HTML vom Browser gerendert. Dort kann auch Java-Script zum Einsatz kommen.
In bestimmten Situationen ist es erforderlich, dass JS im Kopf oder Fußbereich der HTML-Seite eingefügt wird. Das geht über das HTML-Makro leider nicht. Dafür müssten Sie über den Confluence-Admin-Bereich gehen.
Insgesamt fehlt mir immer noch der eigentliche Kontext. Welche konkreten Beispiele für diesen Satz können Sie geben: “Somit habe ich angefangen zu experimentieren, was möglich ist, um einfach und auch komplexere Funktionen zu integrieren und Wert einer Seite massiv zu erhöhen.”
Um es offen zu sagen: Ich vermute, dass Ihre Ziele mit etwas mehr Breitenwissen zu ganz anderen Aktionen führen würden und Sie sich gerade in etwas verrennen, was nicht besonders erfolgsversprechend ist. Aber ohne Kontext ist das eine reine Spekulation.
ich habe versucht, das Beispiel Bootstrap Collapse auf w3 umzusetzen. Der Grund dafür ist, dass mir das Expand Macro nicht ausreicht. Die Umsetzung über reines JavaScript, wie beschrieben im How TO - Collapse von w3 läuft nicht ganz fehlerfrei.
Bootstrap läuft super aber mit den benannten Problemen.
ich bin ein Entwickler aus einem Produktteam bei Seibert Media. Ich habe mir gestern mal kurz Zeit genommen, um die von dir gestellte Frage zu lösen. Es ist möglich, die von Confluence verwendete jQuery-Version für einen bestimmten Gültigkeitsbereich zu ersetzen. Um das zu prüfen, habe ich mal eine lokale Instanz von Confluence aufgesetzt und dort das HTML-Makro freigeschaltet und etwas Code geschrieben. Hier das Ergebnis auf der Seitenansicht:
Man kann sehen, dass dort Elemente von Bootstrap enthalten sind, also nicht nur Funktionalität, sondern auch der Look von Bootstrap übernommen wurde. Das reine Einfügen des Bootstrap-Javascripts reicht also nicht aus, man muss auch das CSS auf der Seite per JavaScript injecten, damit der Look passt. Soweit so gut.
Es gibt allerdings mehrere Probleme und Risiken, warum sowas auf keinen Fall in einer produktiven Instanz gemacht werden sollte:
Bootstrap-JS ist ohne das entsprechende CSS nicht sinnvoll. Die Elemente sehen dann einfach aus wie Standard HTML-Elemente, was sehr unschön ist. Fügt man aber das CSS ein, so hat man keine Garantie dafür, dass nur Elemente innerhalb des HTML-Makros gestylt werden. Auf dem Screenshot ist ersichtlich, dass z.B. das Space-Logo verschoben ist, das Site-Logo verkleinert wurde und auch andere Elemente verändert wurden. D.h. im Zweifel zerstört das Bootstrap-CSS den kompletten Look einer Confluence-Seite.
Noch viel gravierender ist die Tatsache, dass überhaupt das HTML-Makro im System freigeschaltet ist. Im Standard ist das Makro deaktiviert und Atlassian rät vehement davon ab, dieses zu aktivieren, und das aus guten Gründen. Mit eingefügtem JavaScript auf einer Seite ist es möglich, dass jeder Benutzer z.B. die komplette Seite verändert und Daten manipuliert, die für einen Betrachter zunächst gar nicht ersichtlich oder verständlich sind. Im einfachsten Falle kann das JavaScript dazu führen, dass die Seite nicht mehr editiert werden kann, weil der Button entfernt wurde. Oder z.B. könnten die Likes und Kommentare manipuliert werden. Viel kritischer hingegen ist die Möglichkeit, mit eingefügtem JavaScript Cross-Site-Scripting zu ermöglichen. So könnte ein Benutzer ein JavaScript schreiben, was einem anderem Benutzer beim Einfügen von Kommentaren auf dieser Seite irgendwelche falschen Daten beimischt. Oder das JavaScript könnte das soeben verfasste Kommentar, den Benutzernamen, den Benutzer-Schlüssel und andere Details einfach an einen anderen Server schicken, um dort Daten zu sammeln (Stichwort DSGVO). Es ist also möglich, mit Hilfe von Scripting auf Seiten das System zu manipulieren.
Atlassian hat dazu auch eine Dokumentation verfasst, die auf jeden Fall in Betracht gezogen werden sollte: Atlassian Support - HTML Macro
Ich würde also eher dazu raten, das Makro bei Ihnen im System wieder komplett abschalten zu lassen. Stattdessen wären die genauen Beweggründe und Use Cases für die funktionalen Veränderungen am System deutlich interessanter, die sich wiederum mit Erweiterungen mittels entwickelter Apps (die wiederum solche Veränderungen wirklich gekapselt vornehmen können) abbilden lassen.
Das gleiche gilt für das Bootstrap-JS oder nur für das Bootstrap-CSS?
Wenn nur für das CSS, wie kann die Gültigkeit des JS begrenzt werden.
Die Gefahr ist bekannt aber wird in Zukunft entschärft durch Configuring Confluence - Configuring the Whitelist. Mittelfristig ist es das Ziel, dieses durch experimentieren erhaltenswerte befunden Funktionalität in Makros oder Apps zu erhalten.
Die momentanen Situation ist aber, dass das die breite Anwendung von Confluence noch sehr jung ist und nur ich und sehr wenige andere es so intensiv einsetzten. Das Risiko ist somit noch überschaubar,. Es ist aber das Ziel, in absehbar Zeit die Testinstanz am Laufen zu zu haben, wo dann solche Experimente gemacht werden können mit dem Ziel sie in Macros oder Apps zu überführen, welche in unsere Bitbucket Instanz gepflegt werden sollen.
Gerne würden wir auf einen Marketplace zurückgreifen aber kann dieser nicht lokal aufgesetzt werden oder die App nur einem begrenzten Benutzerkreis über den Atlassian Marketplace verfügbar gemacht werden.
Die Entscheidungsprozess sind bei uns nicht die schnellsten und wechselt nun zum neunen Montag der IT-Chef, was das Ganze sicher erstmal nicht beschleunigt. Somit ist das HTML Macro vorerst, dass einzige Mittel mit wenig Aufwand signifikanten Fortschritt zu erzielen in Sachen Funktionserweiterung. So lange dies in einem begrenzten Rahmen bzw. abgestimmt bleibt ist dies vorerst soweit in Ordnung.
hier zunächst mal der Code, wie ich das Ganze zum Laufen bekommen habe:
<script>
// Aktuelle jQuery-Version zwischenspeichern
window.oldjQuery = jQuery;
// CSS von Bootstrap nachladen
$("head").append($('<link rel="stylesheet" type="text/css" />').attr('href', 'https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css') );
</script>
<!-- Externe JS-Ressourcen laden -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<!-- Custom HTML START -->
<button type='button' class='btn btn-lg btn-danger' data-toggle='popover' title='Popover title' data-content='And heres some amazing content. Its very engaging. Right?'>Click to toggle popover</button>
<div class="jumbotron text-center">
<h1>My First Bootstrap Page</h1>
<p>Resize this responsive page to see the effect!</p>
</div>
<div class="container">
<div class="row">
<div class="col-sm-4">
<h3>Column 1</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
</div>
<div class="col-sm-4">
<h3>Column 2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
</div>
<div class="col-sm-4">
<h3>Column 3</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris...</p>
</div>
</div>
</div>
<!-- Custom HTML END -->
<script>
// Neues JS benutzen, um die Bootstrap-Funktionen zu initialisieren
// Das neue JS gilt nur innerhalb dieses Blocks!
"use strict";
(function (newJQuery) {
newJQuery('[data-toggle="popover"]').popover();
}(jQuery));
</script>
<script>
// Neues JS im window-Scope wieder durch das alte ersetzen inkl. der $- und AJS.$-Shortcut-Variante
window.jQuery = oldjQuery;
window.$ = oldjQuery;
window.AJS.$ = oldjQuery;
</script>
Bzgl. des Gültigkeitsbereichs von JS: Beim Selbstgeschriebenen JavaScript kann man noch darauf achten, dass sich das Ganze nur auf die Inhalte des Makros bezieht, indem man z.B. auf Selektoren achtet (ähnlich wie bei konventionellem CSS) und keine globalen Inhalte manipuliert. Allerdings wird ja hier auch aus externen Quellen JavaScript nachgeladen, also eine neue JQuery-Version, Bootstrap und auch das Popper-JS, damit, wie in diesem Beispiel demonstriert, ein Popup angezeigt werden kann. Dabei kann man sich nie sicher sein, ob dieses extern geladene JS irgendwas im globalen Scope beeinflusst und eine Einschränkung auf das HTML-Makro ist hier ebenfalls nicht möglich. Das CSS von Bootstrap hier wegzulassen ergibt aber auch nicht soviel Sinn, da der Look der Elemente komplett verloren ginge. Das dreispaltige Layout aus dem Beispiel würde dann ebenfalls nicht mehr funktionieren. Gleichzeitig ändert das CSS leider auch Elemente in Confluence, d.h. es schwierig abzuwägen, was hier die richtige Entscheidung ist. Auf jeden Fall klingt es gut, dass perspektivisch die Funktionalität solcher Makros in eigene Apps ausgelagert werden soll :).
Das mit dem Whitelisting ist korrekt, es hält allerdings auch niemanden davon ab, die Inhalte auf der gerade angezeigten Seite einfach zu ändern bzw. Daten zu manipulieren. Solche Fälle sind mit dem Whitelisting nicht abdeckbar. Es ist auch denkbar, dass durch viele HTML-Makros auf mehreren Seiten die Performance dieser Seiten darunter lädt. Das komplette Nachladen und Ausführen von Bibliotheken wie jQuery oder Bootstrap trägt dazu bei.
das stimmt aber das begrenzt sich aber auf interne Bösewichte. Hinzukommt das die Personen, die ich abholen möchte, mit einem einfach und ansprechenden aber dennoch umfangreichen Informationsangebot in Confluence würden doch eine überraschende grosse Expertise an den Tag legen, nur Ansatzweise solche Manipulationen vorzunehmen , bzw. was noch wichtiger ist, dass Potential im guten wie im bösen zu begreifen.
Ich glaube bis dahin haben wir noch einen sehr mühsamen Weg vor uns und bis dahin werde wohl die Sachem wie die Testinstanz dann hoffentlich am laufen sein .
Kurze anderer Frage, seit ihr für Backend-Fragen auch so gut aufgestellt. Habe noch eine letzende Frage (Projekt) bevor darin geht produktive Inhalte zu erstellen. Dies werde ich noch als neue Frage stellen.
Hoi zäme,
ich habe endlich die Zeit gefunden, euren Code in Detail zu studieren und ein wenig dazu zu recherchieren. Meine unendliche Neugier ließ mich einfach nicht in Ruhe und somit kann ich das Thema nicht abschließen, bevor ich es nicht vollumfänglich Verstanden habe.
Es kommt nun wie es kommen musste, ich hätte hier und da nun ein paar Fragen, bzw. Anmerkungen .
2 und 3 sind nur Erläuterungen zu meinem Verständnis der Thematik und 4 ist die eigene Auflösung zu einer Frage. Sie könnten aber helfen die restlichen Punkte besser zu interpretieren .
Es geht schon mit der ersten Zeile los: window.oldjQuery = jQuery;
Hier wird dem Window-Objekt, welches ein offenes Fenster repräsentiert (siehe Window - Web APIs | MDN, einfach eine Eigenschaft hinzugedichtet.
Ich verstehe das Window-Objekt als standartisiertes Objekt, in dem sich z.B. das document-Objekt, welches weidrum den DOM enthält (siehe Document- Web APIs | MDN, befindet. Nun wird dem Window-Objekt mir nichts dir nichts einfach eine weitere Eigenschaft (oldjQuery) hinzugefügt.
Geht das ohne Weiteres? Mir wäre das neu, wenn das so schlicht geht. Ich finde dazu nicht wirklich etwas. oldjQuery wird in einem Skript zu einem ganz ähnlichem Thema auf Running two versions of jQuery AND two versions of jQueryUI - Stack Overflow verwendet aber dort wird sauber deklariert var oldJQuery = jQuery;, ähnliches finde ich noch in how to solve the Jquery version conflicts - Stack Overflow aber dort ist window nicht involviert.
Hat es vielleicht etwas mit dem Option()-Konstruktor zu tun, wie auf Option() - Web APIs | MDN erklärt?
Zumindest fand ich eine Erklärung für Ähnliches im Skript oben, wie z.B. window.jQuery am Schluss. So werden, wenn ich es richtig verstehe, eingebundene Skripte als Objekte hinzugefügt, welche im globalen Kontext verfügbar sind, siehe javascript - What does window.jQuery and window.$ mean? - Stack Overflow.
als nächstes hätten wir den DOM, welchen ich hier mal festhalte, da ihn später in meinen Erläuterungen noch brauche.
Sinn und Zweck sind mir soweit bekannt. Er repräsentiert die aus dem im HTML-Quellcode festgehalten Text entstandene Objektstruktur, welche das Abbild der HTML-Seite im Arbeitsspeicher ist (schön erklärt in JavaScript/DOM – SELFHTML-Wiki).
Das liegt daran, dass durch die Aufbereitung des HTML-Quellcodes (durch den sogennanten Parser) die verschiednen Skrip- und Programmiersprachen ,wie html, javascript oder CSS, diese zu einem strukturierten aber dynamischen Objekt umgewandelt werden (siehe Document Object Model (DOM) - Web APIs | MDN).
Die Dynamik bzw. Interaktivität wird durch das Event()-Objekt des DOM bereitgestellt, welches parallel zum document-Objekt angesiedelt ist (Bild, Bild).
Jetzt hätten wir noch jQuery.
Es handelt sich dabei um DIE JavaScript-Bibliothek. Es vereinfacht viele JavaScript-Funktionen, die im Web besonders häufig benötigt werden. Die Arbeit wird komfortabler und der Code kürzer und somit deutlich leichter zu warten. Eine Besonderheit von jQuery ist beispielsweise, dass es den Zugriff auf DOM-Elemente sehr simpel und bequem macht (schön erklärt in Was ist jQuery? - Dev-Insider und Was ist jQuery? - medani web & design).
Typischerweise wird durch den Zugriff auf jQuery mit der $ -Funktion oder, um Kompatibilitätsproblemen mit anderen Bibliotheken aus dem Weg zu gehen und eine bessere Lesbarkeit zu erreichen, mit der jQuery-Funktion ein Objekt erzeugt.
$("div.test, p.quote")`
// oder auch`
jQuery("div.test, p.quote")`
Um mit mehreren Bibliotheken, die das $-Zeichen als Aufruf nutzen, arbeiten zu können, kann man dieses bei jQuery deaktivieren. Folgendes gibt das $-Zeichen für andere Bibliotheken frei: jQuery.noConflict();
Nach der Einführung in 2 und 3 nun zum nächsten Verständnisproblem: window.oldjQuery = jQuery;
Bisher war wir nicht klar, was mit jQuery bezweckt ist. So hatte ich nach den Besonderheiten des . und der () gesucht und bin dabei auf folgendes gesstossen
und war zu der Überzeugung gekommen, dass hier ein jQuery-Objekt deklariert wird aber der Sinn und Zweck war mir nie klar.
aber habe ich gerader erst jquery/3.3.1 in den Pfaden zu den Javascript-Bibliotheken, welche nachgeladen werden, entdeckt .
Somit wird die bisherige jQuery-Bibliothek in window.oldjQuery gesichert.
Hier mal ein konstruktive Anmerkung zum CSS nachladen.
Durch $("head").append($... wird nun bootstrap.min.css dem DOM hinzugefügt. Dabei wird dem HTML internal CSS, welcher im <style> Bereich von HTML <head> abgelegt ist, der Inhalt von bootstrap.min.css am Ende von <style> angehängt. Dies sehe ich doch richtig so?
Da das HTML-Skript sequentiell eingelesen wird, hat dies zur Folge, dass bevor definierte Stilregeln für HTML-Elemente durch die neuen Stilregeln aus bootstrap.min.css ersetzt werden, da diese nach den bisherigen Stilregeln eingelesen werden und somit die Stilregeln für die entsprechenden HTML-Elemente überschrieben werden.
Meine Frage dazu ist nun, auf welche HTML-Elemente werde die neuen Stilregeln nun angewendet, auf noch zu erzeugende HTML-Elemente oder auch auf die schon vorhandenen? How CSS works - Learn web development | MDN erklärt das Theme DOM und CSS sehr gut aber finde ich dort nichts brauchbares zum dynamischen nachladen von CSS. Bisher habe ich nur die Methode loadCSS gefunden.
auswirkung auf alle HTML-Elementen die über hier das Event()-Objekt des DOM mit der jQuery Biblotithek verbunden sind.
Aber mir kommen da Zweifel. Meine andere Interpretation ist, dass dem Knopf
mit folgender Funktion um eine Methode aus dem neuen jQuery erweitert wird
Mein einziger Rückschluss dazu, dass dies nur mit diesen Knopf passiert basiert auf
und das darauf das alte jQuery wieder geladen wird.
Hinzu kommt, wenn ich How to Create Interactive Websites with JavaScript – Kathryn Hodge – Medium richtig verstehe, muss einem Element explizit mit einer JavaScript-Funktionen verbunden werden, welches über die JavaScript-Bibloitheken instanziert wird.
Diese neue Methode ist nun für das entsprechende Element in der Objektstruktur des DOM hinterlegt und somit auch losgelöst von der Quelle. So würde ich zumindest das Nachladen vom neuen jQuery und das spätere Nachladen vom alten jQuery verstehen, bzw. die sehr lokale Gültigkeit des neuen jQuery .
Wo ich aber noch Schwierigkeiten habe ist der Ausdruck
Es sind nicht wenige Fragen zusammengekommen. Ich hoffe ich überbeanspruche hier niemanden aber es wärew super, wenn wir das Thema zu einem vollumfänglich erklärendem Ende bringen.
Ich bin zudem noch auf How to limit scope of a function in javascript/ jquery [duplicate] gestoßen, was unter Umständen auch noch hiflreich sein könnte.