web-dev-qa-db-fra.com

Comment fonctionnent les assistants de balise CDN "asp-fallback- *" d'ASP.NET Core?

Je comprends ce que le asp-fallback-* les assistants de tag le font. Ce que je ne comprends pas, c'est comment.

Par exemple:

<link rel="stylesheet"
      href="//ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css"
      asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
      asp-fallback-test-class="sr-only"
      asp-fallback-test-property="position"
      asp-fallback-test-value="absolute" />

Cela charge bootstrap à partir du CDN, et charge la copie locale si le CDN est en panne.

Mais comment décide-t-il de faire cela? Je suppose qu'il vérifie asp-fallback-test-class, asp-fallback-test-property, et asp-fallback-test-value. Mais que signifient ces attributs?

Si je veux connecter une autre bibliothèque à un CDN, je devrai fournir quelque chose pour ceux-ci, mais je ne sais pas quoi y mettre.

Il existe de nombreux exemples de cela en action, mais je ne trouve pas d'explications sur la façon dont cela fonctionne.

MISE À JOUR
Je n'essaie pas vraiment de comprendre comment fonctionnent les assistants de balise - comment ils s'affichent, etc. J'essaie de comprendre comment choisir des valeurs pour ces attributs. Par exemple, le script de secours jQuery a généralement asp-fallback-test="window.jQuery" ce qui est logique - c'est un test pour voir si jQuery s'est chargé. Mais ceux que j'ai montrés ci-dessus sont très différents. Comment les choisit-on? Si je veux utiliser une autre bibliothèque fournie par CDN, je devrai spécifier des valeurs pour ces attributs ... que dois-je utiliser? Pourquoi ceux-ci ont-ils été choisis pour le bootstrap?

MISE À JOUR 2
Pour comprendre comment fonctionne le processus de secours lui-même et comment ces balises sont écrites, voir la réponse de @ KirkLarkin. Pour comprendre pourquoi ces valeurs de test ont été utilisées, voir ma réponse.

13
lonix

TL; DR :

  • Une balise <meta> Est ajoutée au DOM qui a une classe CSS de sr-only.
  • Un code JavaScript supplémentaire est écrit dans le DOM, qui:
    1. Localise ledit élément <meta>.
    2. Vérifie si ledit élément a une propriété CSS position qui est définie sur absolute.
    3. Si aucune valeur de propriété n'est définie, un élément <link> Supplémentaire est écrit dans le DOM avec un href de ~/lib/bootstrap/dist/css/bootstrap.min.css.

La classe LinkTagHelper qui s'exécute sur vos éléments <link> Insère un élément <meta> Dans le code HTML de sortie qui reçoit une classe CSS de sr-only. L'élément finit par ressembler à ceci:

<meta name="x-stylesheet-fallback-test" content="" class="sr-only" />

Le code qui génère l'élément ressemble à ceci (source):

builder
    .AppendHtml("<meta name=\"x-stylesheet-fallback-test\" content=\"\" class=\"")
    .Append(FallbackTestClass)
    .AppendHtml("\" />");

Sans surprise, la valeur de FallbackTestClass est obtenue à partir de l'attribut <link> Du asp-fallback-test-class.

Juste après l'insertion de cet élément, un bloc <script> Correspondant est également inséré ( source ). Le code pour cela commence comme ceci:

// Build the <script /> tag that checks the effective style of <meta /> tag above and renders the extra
// <link /> tag to load the fallback stylesheet if the test CSS property value is found to be false,
// indicating that the primary stylesheet failed to load.
// GetEmbeddedJavaScript returns JavaScript to which we add '"{0}","{1}",{2});'
builder
    .AppendHtml("<script>")        
    .AppendHtml(JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName))
    .AppendHtml("\"")
    .AppendHtml(JavaScriptEncoder.Encode(FallbackTestProperty))
    .AppendHtml("\",\"")
    .AppendHtml(JavaScriptEncoder.Encode(FallbackTestValue))
    .AppendHtml("\",");

Il y a quelques choses intéressantes ici:

  • La dernière ligne du commentaire, qui fait référence aux espaces réservés {0}, {1} Et {2}.
  • FallbackJavaScriptResourceName, qui représente une ressource JavaScript qui est sortie dans le HTML.
  • FallbackTestProperty et FallbackTestValue, qui sont respectivement obtenus à partir des attributs asp-fallback-test-property et asp-fallback-test-value.

Jetons donc un œil à cette ressource JavaScript ( source ), qui se résume à une fonction avec la signature suivante:

function loadFallbackStylesheet(cssTestPropertyName, cssTestPropertyValue, fallbackHrefs, extraAttributes)

En combinant cela avec la dernière ligne du commentaire que j'ai appelé plus tôt et les valeurs de asp-fallback-test-property Et asp-fallback-test-value, Nous pouvons penser que cela est invoqué comme suit:

loadFallbackStylesheet('position', 'absolute', ...)

Je ne vais pas creuser dans les paramètres fallbackHrefs et extraAttributes car cela devrait être quelque peu évident et facile à explorer par vous-même.

L'implémentation de loadFallbackStylesheet ne fait pas grand-chose - je vous encourage à explorer l'implémentation complète par vous-même. Voici le contrôle réel de la source:

if (metaStyle && metaStyle[cssTestPropertyName] !== cssTestPropertyValue) {
    for (i = 0; i < fallbackHrefs.length; i++) {
        doc.write('<link href="' + fallbackHrefs[i] + '" ' + extraAttributes + '/>');
    }
}

Le script obtient l'élément <meta> Pertinent (il est supposé être directement au-dessus du <script> Lui-même) et vérifie simplement qu'il a une propriété position qui est définie sur absolute. Si ce n'est pas le cas, des éléments <link> Supplémentaires sont écrits dans la sortie de chaque URL de secours.

13
Kirk Larkin

Ok je pense que je comprends maintenant, en combinant la réponse de @ KirkLarkin et le bon sens.

Le sr-only est appliqué à un élément caché meta. Si bootstrap est chargé, cet élément obtiendrait une valeur CSS de position:absolute. Donc, cela est testé, et si c'est le cas, cela signifie que Bootstrap a été chargé.

Donc, pour toute bibliothèque, vous devez choisir un bon exemple de quelque chose que seule cette bibliothèque peut faire, et styliser une balise <meta> cachée en conséquence, puis spécifier le style CSS à tester et la valeur que vous attendez.

Pour javscript, c'est encore plus facile, car vous pouvez simplement tester la bibliothèque elle-même, qui a généralement une variable bien connue ajoutée au window ou quelque chose au DOM. Donc pour jQuery c'est window.jQuery, et pour Bootstrap il peut être testé comme window.jQuery && window.jQuery.fn && window.jQuery.fn.modal et ainsi de suite.

6
lonix