SVG interattivo usando <object>?

Sto cercando di incorporare una visualizzazione dei dati interattiva basata su SVG. Sto generando l’SVG da un sistema separato (ma sempre nello stesso dominio di secondo livello della mia installazione Discourse). Ho provato a incorporare l’SVG utilizzando un tag OBJECT…

<object type="image/svg+xml" data="full_URL_to_foo.svg">
(viene visualizzato se il caricamento dell'oggetto fallisce)
</object>

Se incorporo semplicemente quell’SVG (che viene generato dinamicamente ogni volta) con un tag IMG, la visualizzazione appare, ma (come mi aspettavo) non c’è interattività…

<img src="full_URL_to_foo.svg">

Suggerimenti o indicazioni su dove posso trovare informazioni su SVG e Discourse? :slight_smile:

1 Mi Piace

Il modo più semplice per far funzionare questa funzionalità è utilizzare un iframe. Aggiungi il dominio SVG all’impostazione del sito allowed_iframes e inseriscilo in un post utilizzando HTML.

5 Mi Piace

Hmmmm, quindi questa è la via facile.

Esiste una via difficile che posso provare?

…perché voglio avere link nell’SVG che cambiano la posizione del browser. I link nell’SVG, all’interno di un IFRAME, modificano ciò che viene mostrato nell’IFRAME…

Sospetto che incorporare JavaScript nel topic, subito prima dell’IFRAME, e chiamare una funzione JavaScript nella pagina tramite onclick nell’SVG… non funzionerà nemmeno.

Ho senso? Dovrei aggiungere un po’ di codice JavaScript leggero, come in Mitigate XSS Attacks with Content Security Policy, e poi provare a chiamarlo dall’interno dell’SVG nell’IFRAME? …o “nell’IFRAME” è una fortezza inespugnabile?

Forse dovrei chiedere come posso incorporare direttamente l’SVG nella pagina? Poi usare il codice JavaScript iniettato tramite theme-component per interagire con il mio altro server e aggiornare dinamicamente l’SVG?

Per favore, dammi una mano :slight_smile:

2 Mi Piace

Inserire l’SVG nel post contrassegnato da un div speciale di delimitazione e utilizzare un componente del tema per trasformarlo in un tag object tramite il callback decorateCooked potrebbe funzionare. Consulta la Guida per sviluppatori ai temi Discourse.

3 Mi Piace

…nel caso qualcuno stia seguendo, decorateCooked() è deprecato. Sto sperimentando con decorateCookedElement() invece.

1 Mi Piace

Sto avendo problemi con CORS/Access-Control-Allow-Origin. Non sono pratico di come funziona…

Ho due siti: il sito Discourse ospitato (forum.moversmindset.com) e un sito WordPress basato su Apache (moversmindset.com). Nota che non c’è contenuto evidente sul sito WordPress: genera solo feed RSS, fornisce file multimediali, ecc. Se si accede al dominio, viene reindirizzato semplicemente al forum.

Ho una directory che restituisce risposte di tipo SVG alle richieste GET. Ad esempio (non l’URL reale) https://moversmindset.com/foo/bar.php

Nel mio tema Discourse sto sperimentando codice JavaScript (che diventerà infine un plugin). Chiamo api.decorateCooked() su specifici DIV che hanno alcuni attributi data-custom aggiunti. Quindi, all’interno della funzione chiamata da decorateCooked(), sto facendo qualcosa del genere:

$.get(‘https://moversmindset.com/foo/bar.php’ … bla bla blah

Quindi voglio recuperare l’SVG e poi aggiungerlo al DOM. Ma la console degli errori del browser dice:

Domanda:

Significa che devo configurare CORS sull’installazione di Discourse o su Apache/WordPress?

Ho già configurato https://moversmindset.com come dominio consentito in CORS su Discourse.

2 Mi Piace

Penso che sia da questa parte. Puoi dare un’occhiata a Access-Control-Allow-Origin header - HTTP | MDN se non l’hai già fatto e vedere se ti dà qualche indizio?

4 Mi Piace

piccolissimi passi, ma SÌ!

Ho dovuto aggiungere un header Access-Control-Allow-Origin sul server apache/WP. Questo ha reso felice il j/s (proveniente dalla piattaforma Discourse). Grazie.

3 Mi Piace

Ho continuato a capire tutto questo lentamente. Per porre la mia domanda è necessaria molta configurazione:

SVG

Ho un server web che genera SVG. Per questa domanda, genera un SVG di test molto semplice…

<svg xmlns="http://www.w3.org/2000/svg" stroke-linejoin="round" viewBox="0 0 100 100">
<path d="M50,4L4,50L50,96L96,50Z" stroke="#40638C" stroke-width="3"></path>
<path d="M50,5L5,50L50,95L95,50Z" stroke="#333" fill="#40638C" stroke-width="3"></path>
<path d="M37,42c-1,0,11-20,13-20c1,0,15,20,13,20h-9c0,8,9,22,12,25l-4,4l-8,-7v13h-10v-35z" stroke="#40495E" fill="#40495E"></path>
<path d="M35,40c-1,0,11-20,13-20c1,0,15,20,13,20h-9c0,8,9,22,12,25l-4,4l-8,-7v13h-10v-35z" stroke="#333" fill="#555"></path>
</svg>

È solo un segno di “unione” dall’aspetto elaborato. Nota che ha quattro elementi PATH.

Inline

Per inserire l’SVG in un post, sto usando un po’ di JavaScript aggiunto tramite il mio tema.

L’obiettivo finale sarebbe creare un plugin vero e proprio. Ma sto solo cercando di realizzare una prova di concetto. Quindi è semplicemente incollato nella sezione <head> della personalizzazione del mio tema:

<script type="text/discourse-plugin" version="0.8">
var UMB = {
    svgload: function(base, target) {
        var url = base + $(target).text();
        $(target).html('');
        $.ajax({
            method: "GET",
            url: url,
            async: false,
            dataType: "text",
            success: function(data) { $(target).append(data); }
        });
        alert('caricato!');
        $(target).children('path').each(function(){alert('ecco un elemento path');});
    },
}
$.fn.umbdv = function() {
    this.each(
        function() {
            UMB.svgload('__URL_REDACTED__', this);
        }
    );
    return this;
};
api.decorateCooked(
  $elem => $elem.children('.cooked div[data-custom="umbdv"]').umbdv(),
  { id: 'umbdv' }
);
</script>

Dove…

var UMB = { è semplicemente una variabile globale che mi evita di avere funzioni anonime gigantesche ovunque.

$.fn.umdv = è [quel che penso sia chiamato] un “plugin” che estende JQuery.

api.decorateCooked( mi permette di manipolare il post prima che venga inviato al browser.

Incantesimo

In un argomento, poi scrivo…

<div data-custom="umbdv">/vtest</div>

UMB.svgload('__URL_REDACTED__', this) viene chiamato per quel DIV.

UMB.svgload() interpreta correttamente la stringa /vtest, compone un URL ed effettua la richiesta AJAX. Esegue con successo append(data) e boop il mio SVG è inline…

Il mio alert() all’interno di UMB.svgload() viene quindi attivato, esattamente come previsto. (È ovviamente un trucco di debug, vero? :))

La domanda (finalmente)

Ho un argomento RISERVATO ALLO STAFF nel mio forum ospitato su Discourse dove puoi vedere questo in azione. (Sto parlando con il personale di supporto di Discourse che può entrare nella mia installazione come utenti Admin.)

https://forum.moversmindset.com/t/svg-experimentation-in-progress/1109

Perché non…

$(target).children('path').each(function(){alert('ecco un elemento path');});

…seleziona nessuno degli elementi PATH?

Non fa nulla—nessun errore. Nulla.

Prossimo passo

Dove andrò se riesco a far funzionare questa banale prova di concetto con alert()

Sono consapevole che il frammento di DOM con cui sto “lavorando” non è ancora connesso al DOM del documento effettivo (nel momento in cui viene chiamato UMB.svgload()). È per questo che mi aspetto che $(target)… sia ciò di cui ho bisogno.

In definitiva, sto inlineando SVG molto più complessi e dovrò usare selettori JQuery più sofisticati. Voglio trovare molti elementi all’interno di $(target) e attaccare gestori di eventi (onclick, per esempio) che chiameranno altre funzioni globali UMB.….

1 Mi Piace

Gli iframe possono modificare la navigazione a livello superiore se lo desideri

http://w3c-test.org/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation_by_user_activation-manual.html

3 Mi Piace

Grazie per il consiglio!

Ma ora preferisco decisamente l’SVG inline.

Comunque. Settimane dopo. Questo non funziona.

Non sembra possibile manipolare gli elementi DOM SVG una volta che sono incorporati nel documento principale. Quindi non riesco a capire come aggiungere trigger di eventi/azioni (cosa che si potrebbe facilmente fare con onclick e simili se l’SVG fosse caricato in un iframe)
(({non} usare un iframe era tutto il mio obiettivo.))

¯\_(ツ)_/¯

1 Mi Piace

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.