IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Re-ouvrir ou accéder à une fenêtre grâce à son "name", que se passe-til si le name est dupliqué ?


Sujet :

JavaScript

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Re-ouvrir ou accéder à une fenêtre grâce à son "name", que se passe-til si le name est dupliqué ?
    Bonjour,

    Résumé :

    Il n'est, semble-t-il, pratiquement pas possible d'empêcher que des fenêtres puissent porter le même nom "name", ceci même si un outil est conçu pour gérer une liste de noms uniques il ne peut empêcher la création de doublons. Par ailleurs tout l'environnement javascript semble supposer qu'un "name" est unique.
    En effet, il peut y avoir des doublons volontaires ou accidentels, mais rien ne semble permettre de les trouver, de le savoir.
    Les questions sans réponse me semblent nombreuses.

    J'ai précédemment ouvert un sujet sur l'utilisation de {window.name} pour accéder via {window.open('',name)} par d'un processus d'accès par leur nom à des fenêtres générées à partir d'une liste de fenêtres connues.

    Tout cela marche bien au départ, mais le principe repose sur la possibilité d'existence d'une correspondance biunivoque entre les "name" créés (liste des fenêtres créées gérée par le parent) et les fenêtres gérées par le navigateur, ce qui peut devenir faux.

    Cette hypothèse peut en effet devenir fausse dans pas mal de cas dont celui de la "duplication" de fenêtre. Alors une question se pose :

    Comment se comporte {window.open("",name)} quand plusieurs fenêtres portent le même nom ?

    Pour l'instant une chose est certaine l'instruction retrouve le handle vers la première fenêtre ouverte, mais bien d'autres questions restent ouvertes et posent de sérieux problèmes :
    • que se passe-t-il quand cette première fenêtre est fermée : le(les) doublon(s) dévien(nen)t-il(s) accessible ou est(sont)-il(s) ignoré(s) ?
    • quel moyen pour accéder à cette(ces) fenêtre de nom pourtant connu mais cachée (peut-être même multiple) et pourtant issus du même parent.
    • comment le concepteur de l'interface peut-il réaliser quelque chose de fiable et comment l'utilisateur peut-il travailler sans erreur s'il y a confusion entre les fenêtres (le concepteur devrait pouvoir "marquer" le doublon, générer une alerte, restaurer des propriétés... changer le name)


    A mon avis, le principe même du "name" suppose au départ du modèle DOM ainsi que toutes les fonctions associées qu'il est unique, ce qui est faux dans la pratique. De plus il n’apparaît pas possible d'interdire la fabrication de doublons. L'idée même que des doublons puissent exister n'est évoquée nulle part (bien que plusieurs articles sur le net traitent de la manière d'obtenir un identifiant unique de fenêtre soit traité, ils semblent passer tous au travers du problème, ignorer qu'il puisse y avoir là un problème).

    Les questions les plus élémentaires que se posent et dont la solution permettrait de mettre en oeuvre des solutions pratique aux problème que j'expose, sont à mon avis :

    • Existe-t-il un moyen pour que lorsqu'une fenêtre est dupliquée (i.e. "dupliquer" sous chrome etc...), lorsqu'elle récupère le focus, le développeur puisse détecter qu'elle est une duplication (via l'objet window).
    • Il y a-t-il un moyen pour retrouver tous les handles vers des fenêtres portant le même nom ? (évidemment on pense à window.open("",name) qui pourrait renvoyer une array : ou en JQ : $(window:name)...)


    Avez-vous une solution ? une idée ? je cherche sans-trouver, tout (je ne détaille pas) se termine en impasse pour l'instant.
    Merci d'avance

    Trebly

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Des éléments de solution ?
    re-Bonjour,

    Grâce aux efforts de formulation que j'ai effectué, j'ai semble-t-il quelques éléments de solution.

    Les derniers test effectués donnent les résultats suivants :

    Quand plusieurs fenêtres portent le même nom l'exécution de {window.open("",name)} renvoie pour chacune des fenêtres un handle vers elle-même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (window == window.open("",window.name)) == true // toujours vrai indépendamment de l'existence de doublons, on pouvait s'y attendre
    Chacune des fenêtres cache son double (window.open("",window.name) ne renvoie pas le même handle à partir de lui-même mais un seul indéterminable quand il y a des doublons.
    Par contre, si je change le nom de la fenêtre courante (window.name=window.name+"(1)"), j'ai alors deux cas :
    1. il existe au moins une fenêtre qui porte mon nom d'origine, alors je récupère le handle et de plus cette fenêtre prend le focus.
    2. il n'existe pas (plus) de fenêtre portant mon précédent nom et alors je récupère une fenêtre vide (blank) et je sais alors que je n'ai pas de double.


    Il serait donc possible d'utiliser le principe suivant pour résoudre le problème des doublons :
    1. le parent crée un fenêtre avec un nom générique qui pourra être unique.
    2. chaque fenêtre ainsi créée change automatiquement son nom en ayant vérifié qu'elle était unique, ceci en essayant d'ouvrir son ancien nom
    3. chaque fenêtre vérifie que son nouveau nom est unique


    Mais ce processus ne marche pas, en effet une fenêtre renommée semble ne plus pouvoir être accédée du tout.

    Retour départ ?

    Cordialement

    Trebly

  3. #3
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Il est impossible de créer deux fenêtre de même nom.

    l'ouverture avec un target ou un name (en javascript) ouvre l'onglet ou la fenêtre portant ce nom
    si la fenêtre n'existe pas elle est crée.

    la fenêtre n'a rien à voir avec le DOM le DOM est le contenu d'une fenêtre uniquement lorsque celle-ci contient du HTML ou du XML

    Donc lorsque un lien est cliqué alors que le lien possède un attribut target le lien s'ouvre dans la fenêtre cible et ce-là quel que soit le moyen utilisé pour ouvrir la fenêtre (plugin, javascript du même ou d'un autre site, target du même ou d'un autre site)

    les points importants sont
    • la référence à la fenêtre ouverte
    • la référence à l'oppener


    lorsqu'on ouvre une fenêtre avec window.open on obtient une référence sur la fenêtre cible.
    supposons que l'utilisateur ouvre deux sites A et B

    Le site A ouvre une fenêtre "named" et garde une référence dessus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myWindow = window.open("mapage.html", "named");
    myWindow est une référence à la fenêtre contenant mapage.html

    maintenant le site B ouvre lui aussi un fenêtre "named" et garde lui aussi une référence dessus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    win = window.open("doProcess.jsp", "named");
    que ce passe-t-il à ce moment là ?
    le navigateur repère la fenêtre "named"
    il détecte que le lien n'est plus celui du site A mais du site B
    il rompt la réféence myWindow du site A
    il ouvre doProcess.jsp
    win est une référence à la fenêtre contenant le résultat de doProcess.jsp

    Il se passe exactement le même processus si c'est un lien avec target qui est ouvert à la différence que la page qui ouvre le target ne peut garder de référence à la fenêtre ouverte.


    La référence inverse "oppener"
    lorsqu'on ouvre une nouvelle fenêtre que ce soit avec target ou window.open la fenêtre ouverte garde une référence à la fenêtre qui l'a ouverte.

    Le site A ouvre une fenêtre "named"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    window.open("mapage.html", "named");
    dans named le navigateur garde une référence à la page du site A qui a ouvert la page. en javascript on y a accès via window.oppener.

    maintenant le site B ouvre lui aussi un fenêtre "named"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    window.open("doProcess.jsp", "named");
    que ce passe-t-il à ce moment là ?
    le navigateur repère la fenêtre "named"
    il détecte que le lien n'est plus celui du site A mais du site B
    il vide la fenêtre named
    la fenêtre named ne possède plus de référence au site A
    Il ouvre doProcess.jsp
    et créé une référence à la page du Site B qui a "ouvert" named.

    dans named le navigateur garde une référence à la page du site B qui a ouvert la page. en javascript on y a accès via window.oppener.

    A+JYT

  4. #4
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Citation Envoyé par sekaijin Voir le message
    [...] en javascript on y a accès via window.oppener.
    Attention l'attribut "target" ouvre la porte aux pirates. Il est recommandé de casser le lien vers la fenêtre parent.
    Exemple : <a href="https://d3js.org/" rel="noreferrer noopener" target="_blank">d3.js</a>

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Un cas différent plus étendu et la résolution du problème de doublon possible, synthèse
    Bonsoir,

    OK on va probablement pouvoir avancer, mais mon sujet n'était pas exactement celui là.
    En effet, tout seul, on peut passer systématiquement à coté d'une question... faute de se poser la bonne, à au moins deux ça va déjà mieux.

    Je rappelle mon objectif : gérer un ensemble de tabs ouvertes à partir d'un même site de façon à éviter les réouvertures multiples et pouvoir naviguer à partir d'une liste de onglets ouverts par l'application web.

    Je décris ici mes test et mes conclusions.


    Ce que j'observe avec Chrome Canari et FF et leurs inspecteurs en utilisant la ligne de commandes et le panneau (Chrome inspector ou FF Firebug).
    La plupart des comportements que je décris ne le sont pas dans les documentations immédiatement accessibles, à savoir :

    1- Quand sur une fenêtre nommée par une application web (par une extension) est "dupliquée" (par l'API d'un tabbrowser par exemple), on peut vérifier
    - que les deux on exactement le même name et le même opener
    - que un w=window.open("",''name") sera sans effet en appelant la fenêtre elle-même, ceci pour chacune des deux (ou n)
    - que la deuxième reste invisible depuis l'opener sauf si l'on renomme la première ou elle-même (chaque tab a un name unique)

    2- Si une tab en ouvre une autre, le opener est bien le name de la tab qui envoie la commande. (Att : si l'ouverture se fait par un lien <a href: ...>...</a> avec l'action par defaut il n'y a pas de lien et le opener sera null).

    3- Quand les tab ont un nom unique (d'origine, ou renommées en cas de duplication) il sera alors possible de basculer de l'une à l'autre avec la commande window.open("",iname) ceci à partir d'un membre quelconque de la famille. Ceci reste vrai même si des tabs de la famille sont fermées, y compris les parents quelle que soit la généalogie.

    4- En cas de doublon créé il reste invisible tant que son nom n'est pas changé, mais il ne peut se renommer que lui même (puisqu'il est caché), le code doit alors permettre d'effectuer le test de doublon et de renommer correctement les tabs.

    5- Même si les names sont changés, le concept de famille n'est pas altéré.

    6- Même si les opener.name sont changés, le concept de famille et la hiérarchie n'est pas altérée. Néanmoins, il est bien, en cas de rename de mettre à jour les opener.name pour pouvoir tenir compte de ou afficher la généalogie.

    7- La possibilité d'accès à toutes les tabs d'une même famille à partir de l'une quelconque d'entre elles, autorise d'effectuer des rename et des manipulations de données par un script qui manipule une array des tabs depuis le code de l'une quelconque des tabs de la famille.

    8- un objet "tabs" peut ainsi être créé en tenant compte des comportement décrits, en restant totalement cohérent, à une exception près :

    - recommandation : si une tab est créée avec un lien par défaut via l'url directement on peut affecter le même name sans inconvénient, mais on a créé une autre famille. Cela peut conduire à des confusions puisque deux tabs identiques pourront être ouvertes en appartenant à des familles différentes. Le comportement des familles peut s'entrecroiser puisque les deux tabs identiques utiliseront le même code. Les familles doivent alors pouvoir être identifiées tout en sachant qu'elles ne pourront pas communiquer. Cette identification permet d'éviter les confusions et d'alerter l'utilisateur. Un changement de titre introduisant le N°de famille permet de limiter les difficultés. Il est évident que, à l'intérieur d'une même application il y a intérêt à ne jamais utiliser un lien standard pour ouvrir une nouvelle tab et donc que toutes les tabs ouvertes appartiennent à une même famille. On ne reste cependant pas à l'abri d'une ouverture par un lien externe.

    En conclusion :
    On voit donc que les name (et opener.name) sont une vue externe associée aux identifiants de la gestion des tabs par le navigateur.
    Par contre comme il s'agit du seul accès donné aux applications (pas aux extensions) pour manipuler correctement les tabs il est indispensable de maintenir un lien 1-1 entre les tabs et leur nom, c'est à dire une identité entre la structure interne et celle des noms externes, identité qui n'est pas naturellement assurée.

    Quoique l'usage de window.open soit non recommandé aux développeur d'extensions et que les API tabbrowser les remplacent avantageusement, les développeurs de sites n'ont actuellement pas d'autre outil pour gérer les fenêtres qu'ils ouvrent avec leurs applications.

    Enfin je rappelle que le cadre dans lequel j'ai débroussaillé ce terrain est que j'en avais besoin dans une application qui peut conduire à ouvrir de nombreuses tabs (onglets) ou l'utilisateur peut se perdre, et que je n'ai presque rien trouvé du contenu nécessaire que j'explique ici.
    Il demande certainement des compléments.

    Enfin il faut noter deux points essentiels de mode d'utilisation de window.open :
    • Les commandes window.open(url,name) ouvrent par défaut (sans paramètres autres précisés) des tabs et non des fenêtres.
    • La consommation mémoire n'est pas supérieure à celle d'un onglet standard, ce qui n'est pas le cas si l'on ouvre d'autres vraies "fenêtres" et popups.
    • Les test n'ont été totalement effectués qu'avec chrome canari dernière version, on ne peut donc pas présupposer d'une identité totale de comportement avec d'autres navigateurs.


    Je pense que ce que j'ai décrit ici, qui repose uniquement sur des test, sauf erreur de manipulation (mais les test on été répétés), est une description exacte de ce qui est.

    Cordialement

    Trebly

    Note : ce n'est pas un tuto, mais le simple état relaté des test que j'ai effectué. J'ai bien conscience que, comme je n'ai rien trouvé d'aussi approfondi, un tuto pourrait être produit à partir de ces éléments. Je n'ai pas le temps dans l'immédiat.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Réponse à sekaijin
    Bonjour,

    En complément de mon précédent texte qui est une réaffirmation de propriétés vérifiées, et donc de nature très différente d'une discussion, je répond ici à sekaijin.

    Nous ne parlons pas de la même chose, mais on peut parler des deux.
    Pour ma part je parle de l'utilisation de window.open en javascript et le contexte chrome canari, tu me parles HTML sans préciser le navigateur.
    Pour commenter, je dirais qu'il y a des restrictions dont tu ne fais pas mention. Je les reformule à la fin.

    Tu dis :

    Il est impossible de créer deux fenêtre de même nom.
    l'ouverture avec un target ou un name (en javascript) ouvre l'onglet ou la fenêtre portant ce nom
    si la fenêtre n'existe pas elle est crée.
    C'est vrai pour mon contexte à partir d'une même source : un onglet ouvert par un lien sans "target" ou en indiquant l'url dans la zone

    C'est faux à partir de deux sources distinctes


    la fenêtre n'a rien à voir avec le DOM le DOM est le contenu d'une fenêtre uniquement lorsque celle-ci contient du HTML ou du XML
    Je le concède volontiers, bien d'accord, lapsus je voulais écrire "BOM"

    Donc lorsque un lien est cliqué alors que le lien possède un attribut target le lien s'ouvre dans la fenêtre cible et ce-là quel que soit le moyen utilisé pour ouvrir la fenêtre (plugin, javascript du même ou d'un autre site, target du même ou d'un autre site)
    Ce qui est vrai : quand dans un lien <a href="toto" target="nom_existant"> donne le nom d'une fenêtre existante déjà ouverte à partir du même document, elle sera actualisée et ouverte avec url="toto", mais cela uniquement pour la même famille source, toujours même restriction.

    Ce qui est faux c'est
    quel que soit le moyen utilisé pour ouvrir la fenêtre (plugin, javascript du même ou d'un autre site, target du même ou d'un autre site)
    - On peut avoir ouvert une tab A1 avec une url et un name avec window.open("url1","name1") à partir d'une tab A0 ayant un opener=null puis :
    - exécuter un lien à partir d'une autre tab B0 toujours avec opener=null <a href="url1" target="name1"> on ouvrira un nouvel onglet B1

    Ensuite à partir de Tab A0 : window.open('',"name1") réouvrira A1, un lien <a href="url1" target="name1"> fera de même mais <a href="" target="name1"> changera l'url pour ""
    Et à partir de B0 on ouvrira B1
    Mais jamais on ne re-ouvrira une tab ouverte par l'autre racine : si une Tab B2 de name2 a été ouverte par B0 ou B1, à partir de A0 ou A1 une ouverte window.open("","name2") ouvrira un nouveau membre la famille A avec une url vide donc "blank" (sans titre)

    Pour la suite ce n'est pas du tout ce que j'ai pu vérifier dans l'héritage, alors il y a problème à résoudre, ce que tu décris, tu l'as vérifié sur quel navigateur ?

    Je confirme qu'avec chrome canari dernière version il est impossible d'ouvrir une fenêtre d'un site A d'un autre site B ou du même site (même hostname) mais d'une racine différente (ouvert via la barre de navigation ou autre moyen) même si on en connait le nom. Ce qui, je le concède aussi, n'est pas décrit dans les documentations.
    S'il y avait une telle différence de comportement ce serait évidemment un très sérieux problème global, mais aussi pour moi parce que mon développement devrait avoir plusieurs versions.


    Je viens de tout re-tester.

    Cordialement

    Trebly

  7. #7
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Je n'ai effectivement pas vérifié tous les navigateurs

    il est une chose que les navigateur doivent respecter pour de simple raison de sécurité (chose qui par le passé à posé problème car ce n'était pas le cas)

    si un site A ouvre une fenêtre nommée soit par target soit par window.open
    le navigateur doit garantir qu'un deuxième appel vers le même site retourne la même fenêtre.
    le navigateur doit garantir que si un site B ouvre une fenêtre avec le même nom le site A n'y aura pas accès.

    jusqu'au derniers tests que j'ai fait (il y a déjà quelque temps) la solution retenue était celle que j'ai décrite dans mon post précédent.
    il faut préciser que pour le navigateur un site c'est protocole + domaine + port
    si donc on passe de http à https ou le contraire ce n'est pas le même site (d'ailleurs les CORS sont la pour s'en apercevoir) pareil pour un changement de host ou de port.

    le navigateur ne fait pas de distinction par rapport au chemin de l'url.

    Il existe une autre stratégie pour respecter la sécurité
    si un site A ouvre une fenêtre nommée soit par target soit par window.open
    le navigateur doit garantir qu'un deuxième appel vers le même site retourne la même fenêtre.
    le navigateur doit garantir que si un site B ouvre une fenêtre avec le même nom le site A n'y aura pas accès.

    lors de l'ouverture par B de la fenêtre le navigateur peut ouvrir une autre fenêtre de même nom
    mais dans ce cas
    il doit garantir qu'un deuxième appel par A vers le même site retourne la fenêtre ouverte par A.
    il doit garantir qu'un deuxième appel par B vers le même site retourne la fenêtre ouverte par B.

    Je n'ai pas vu par le passé de navigateur ayant utilisé cette approche. (mais il est vrais que je n'ai pas vérifié ça depuis longtemps)

    l'ouverture de "", "named" est un cas particulier.
    normalement cette ouverture est destinées à permettre à l'appelant d'ajouter dynamiquement des éléments dans la fenêtre.
    là encore je n'ai pas vérifié depuis longtemps mais ce que j'avais noté alors c'est que la page est considérée comme étant dans le domaine de l'appelant (pas de CORS en vue)

    Depuis que les navigateurs se son penché un peu sur la sécurité je n'ai jamais constaté de collision.
    A+JYT

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Le "site" qui crée son "espace de tab" est une tab qui n'a pas d'opener, un paquet de règles complémentaires
    Bonsoir,

    Nous sommes d'accord.

    Je voudrais préciser que le concept de "site" que tu utilise qui me parait ambigu car non clairement défini dans le contexte. Pour que ton propos soit exact il faut une autre définition pour répondre au concept actuel.

    On pourrait penser que le cloisonnement de ce que j'ai appelé par défaut des "familles" pourrait se faire par le "hostname", le "site" serait alors identifié par un hostname et répondrait à un hostname stable et fixe pour la "famille".
    Je ne vois pas immédiatement le problème de sécurité que cela poserait, mais la solution actuelle est à la fois plus restrictive et plus souple.

    Ce que j'appelle ici (pour la première fois) un "espace de tabs" dans lequel les règles que j'ai identifiées est l'ensemble des tabs qui peut être généré à partir d'une tab d'origine qui a été créée par :
    • une ouverture d'url saisie
    • une commande javascript window.open("url")
    • une ouverture par un lien tag <a> sans filiation (mes test sont incomplets mais c'est dans la pratique : href sans target ou _blank, voir ci-dessous)


    et qui génère d'autres tabs en créant un lien opener, par :
    • une commande javascript window.open("url","name")
    • un lien <a href="url" target="name"> ...</a> mais uniquement par click gauche (le click droit natif qui dépend du navigateur et des options force target a "_blank" ou " _self" ce qui crée une tab pour laquelle opener==null

    Mais il faut retenir aussi :
    • Ce n'est pas la présence de l'attribut "opener : window" qui est toujours présent après la création qui maintient le lien à la famille. Si l'on remplace opener par null le lien reste maintenu (je n'ai pas trouvé : non utile a priori le moyen de la décrocher).
    • L'accès à la tab sans actualisation, depuis un autre membre de la famille, de l'"espace de tabs" (pas uniquement le parent) ne peut être obtenu qu'à l'aide d'une seule commande window.open("",name) ou thiswin.focus() quand on a la référence (voir plus loin)
    • Les commandes sont asynchrones donc les commandes continuent d'être exécutées jusqu'à terminaison dans le script d'où est issu la commande.
    • Dans le cas du lien tag <a> il y a toujours actualisation de la fenêtre même si l'url est identique.
    • La fenêtre qui va être ouverte (nouvelle ou existante nommée, par un lien ou window.open) va devenir automatiquement active en récupérant le focus.
    • La commande window.open retourne une référence à la nouvelle fenêtre, par conséquent si mywnew = window.open('url','name1'), une commande issue d'une fenêtre wnew.focus() ré-ouvrira la fenêtre (tout comme window.open("","name1") qui fait la même chose mais renvoie la référence de la tab (fenêtre) et ouvre automatiquement une fenêtre vide.
    • Si la fenêtre mywnew n'existe plus ou pas encore notre mywnew.focus() (ou tout autre) produira une erreur. C'est une manière simple et très économique de vérifier l'existence d'une fenêtre supposée exister que l'on veut ré-ouvrir d'utiliser une commande try { mywnew.focus() } catch...
    • Presque (je n'ai pas trouvé d'exception) toute commande de script pour être exécutée et l'on peut, via notre "mywnew", accéder à toutes les données et objets de cet objet "window" du BOM.
    • Il est alors possible de créer un espace de données partagées entre toutes les tabs de cet espace de tabs... dont le seul lien est d'avoir été créées les unes à partir des autres par les moyens adaptés.
    • ... etc...


    Att: les règles que j'ai décrites ne sont pas exhaustives et peuvent changer tant qu'il n'y a pas de norme et ne sont peut-être ou probablement pas identiques avec tous les navigateurs.

    Cordialement

    Trebly

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Après six mois, compléments d'expérience et simplification, les doublons masqués
    Bonsoir,

    Il s'est passé six mois et j'ai développé des algorithmes de maintenance de familles de fenêtres :

    L'objectif :

    Pour un domaine+port, quoiqu'il arrive pouvoir maintenir l'unicité de fenêtres ouvertes correspondant à une url principale, identifiée par "name" (hors hash) et accessible via window.open('',"name").

    Si indépendamment des noms qui sont un outil d'identification il existe des doublons affichés, l'utilisateur peut avoir ouvert plusieurs fenêtres de modification de même objet (ex: un post dans Wordpress en cours de modification dans deux fenêtres entrainant un conflit et des pertes de données évidemment).

    Les noms devraient permettre normalement d'éviter ce problème. Mais ça ne marche pas à tous les coups en effet quand on ouvre deux fois la même url et que la fenêtre se nomme elle-même du même nom un faux doublon se crée. Faux parce que la première créée devient inaccessible tant que la deuxième n'est pas détruite (il n'y a pas destruction de lien mais on ne trouve que le dernier objet créé dans la pile du même nom).
    Le problème majeur est que seul le cas de l'ouverture via window.open garantit l'unicité. Les plugins de duplication d'onglets posent le même problème.
    La destruction intempestive pose aussi des problèmes en faisant réapparaitre un doublon oublié par exemple.

    Pour parer à ce problème je n'ai trouvé qu'un seul moyen : pouvoir tester si une fenêtre d'un nom donné existe ou non. C'est mon avis après six mois de recul, il est essentiel de pouvoir tester, avant d'ouvrir ou de nommer une fenêtre (window.name='name1'), s'il existe déjà une fenêtre du même nom (qui pourra être masquée si l'on en prend pas garde). pour maintenir l'unicité, si un doublon d'url est autorisé le nom est modifié (i.e. un N° d'instance est ajouté au nom de base de famille associé à l'url).

    Or pour ce faire il n'y a qu'une méthode : voir si window.open("","name") renvoie un handle vers une fenêtre ou ouvre une fenêtre vide.

    C'est malheureusement lourd et très couteux en ressources quand la fenêtre n'existe pas.

    Je ne comprend pas qu'une telle possibilité n'existe pas et je ne vois pas, a priori, de problème de sécurité que cela poserait (à condition de respecter des règles de nommage résistant à des tentatives de piratage par des moyens ad-hoc).

    Je reprend donc dans un nouveau sujet que je vais ouvrir très vite, la proposition que je résume ici :

    window.open("","name1","check=yes") retournerait :

    • - si la fenêtre "name1" existe le handle (la reférence à l'objet fenêtre existant)
    • - si la fenêtre "name1" n'existe pas "null" (ou lieu d'en ouvrir une nouvelle)
    • - en l'absence de la propriété check=yes si la fenêtre "name1" n'existe pas une nouvelle est ouverte (pour ma part je teste qu'elle est nouvelle en vérifiant que son contenu est vide)



    Bien cordialement

    Trebly

    _____________________________________________________________________________________________________________________
    Note 1 : Dans ce cas les algorithmes de contrôle et de nettoyage éventuel sont un peu complexes, mais tout à fait maitrisables. Il peuvent aisément être encapsulés dans un nouvel objet. Les données concernant les fenêtres ouvertes sont stockées dans un cookie de domaine qui est lu et surtout réécrit quand un changement intervient par la fenêtre qui a le focus.

    Note 2 : Je nomme toute fenêtre résultant d'une requête en utilisant window.name=name; Préalablement je teste (je suis obligé de) qu'il n'y a pas de fenêtre portant ce nom. Pour cela j'utilise window.open('',<name>). Cependant sans paramètre window.open ouvre par défaut un onglet, le test d'existence d'une fenêtre perturbe alors considérablement l'affichage, donc je lance l'instruction avec un paramètre ce qui ouvre si elle n'existe pas une fenêtre popup que je referme immédiatement. Ce n'est pas bien beau mais ça marche et surtout j'affiche un message d'attente sur le dessus...
    Dans le cas de doublon pour la même url suivant le cas :
    • L'ouverture après alerte est refusée, on bascule vers la fenêtre existante (focus()) et l'on ferme le doublon.
    • L'ouverture est acceptée avec une alerte à l'utilisateur sur les risques éventuels (mais cela permet de consulter un même texte par exemple en deux points différents).


    Note 3 : Il me semble que sur le plan du développement une telle évolution serait très aisée à réaliser et légère y compris dans la gestion des compatibilités ascendantes.

    Note 4 : La base de la disposition actuelle a été me semble-t-il de dire que si l'on nommait un popup en renvoyant la référence existante si la commande de création était répétée, on évitait la création de doublon, mais ceci à partir du seul cas de filiation ("dependent" paramètre option de window.open qui à des chances d'être abandonné...). La question n'a probablement pas été posée bien plus loin. Le problème devient sérieux à partir du moment où l'on gère des données, pas dans le cas de simples affichages.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Identification des fenêtres ouvertes par un application (non puglin) : une solution ?
    Bonsoir,

    La question que je pose aujourd'hui, et pour laquelle j'ai une réponse que je propose, est la suivante :

    Comment une application, qui n'est pas un plugin, peut-elle gérer l'ensemble des fenêtres qu'elle peut ouvrir dans un navigateur ?

    Pour mener à bien cette tâche il est nécessaire, si l'on veut pouvoir maintenir la cohérence de données saisies, quand il y a lieu, non seulement de pouvoir nommer les fenêtres ouvertes ( window.open : -> onglets ou pop-up), ceci bien évidemment en respectant des règles strictes, mais aussi de pouvoir vérifier si elles existent ou non.


    L'objectif :

    Pour un domaine+port, l'objectif est que quoiqu'il arrive on puisse maintenir l'unicité de fenêtres ouvertes correspondant à une url principale, identifiée par "name" (hors hash) et accessible via window.open('',"name").

    Le problème posé provient de deux difficultés majeures :
    • deux sessions différentes d'un même domaine peuvent ouvrir des fenêtres de même nom. Ces fenêtres se masquent mutuellement.
    • tester si une fenêtre a déjà été ouverte nécessite d'ouvrir une fenêtre vide quand elle n'existe pas, obligatoirement la créer, ceci pour la détruire immédiatement après si elle est nouvelle.


    Exposé détaillé des problèmes posés, exemples:

    Si indépendamment des noms qui sont un outil d'identification il existe des doublons affichés, l'utilisateur peut avoir ouvert plusieurs fenêtres de modification de même objet (ex: un post dans Wordpress en cours de modification dans deux fenêtres) entrainant un conflit et des pertes de données bien évidemment.

    Les "noms" devraient permettre normalement d'éviter ce problème. Mais ça ne marche pas à tous les coups, en effet quand on ouvre deux fois la même url (en créant ainsi une nouvelle session) et que la fenêtre se nomme elle-même du même nom, un faux doublon se crée. Faux parce que la première créée devient inaccessible tant que la deuxième n'est pas détruite (il n'y a pas destruction de lien mais on ne trouve que le dernier objet créé dans la pile du même nom avec l'équivalent d'un FIFO - fisrt-in-first-out).
    Le problème majeur est que seul le cas de l'ouverture via window.open garantit normalement l'unicité, malheureusement seulement dans une même session.
    Il faut donc pratiquement renommer une fenêtre pour savoir si elle n'en cache pas une autre du même nom.
    Les plugins de duplication d'onglets posent le même problème.
    La destruction intempestive pose aussi des problèmes en faisant réapparaitre un doublon oublié par exemple.

    La parade

    Pour parer à ce problème je n'ai trouvé qu'un seul moyen : pouvoir tester si une fenêtre d'un nom donné existe ou non.
    A mon avis, confronté à cette question et un an de recul, c'est un point essentiel que de pouvoir tester, avant d'ouvrir ou de nommer une fenêtre (window.name='name1') s'il existe déjà une fenêtre du même nom (qui pourra être masquée si l'on ne prend pas garde). Pour maintenir l'unicité des noms quand un doublon d'url est autorisé (afficher plusieurs fois le même document) le nom courant peut-être modifié pour chaque instance avec un même nom de "base" (i.e. un N° d'instance est ajouté au nom de "base de famille" associé de manière univoque à l'url).

    Or pour ce faire il n'y a aujourd'hui qu'une seule et unique méthode : voir si window.open("","name") renvoie un handle vers une fenêtre ou ouvre une fenêtre vide.

    C'est malheureusement lourd et très couteux en ressources quand la fenêtre n'existe pas.

    Je ne comprend pas qu'une telle possibilité n'existe pas et je ne vois pas, a priori, de problème de sécurité que cela poserait (à condition de respecter des règles de nommage résistant à des tentatives de piratage par des moyens ad-hoc).

    Ce problème est traité pour les plugins qui accèdent à la gestion des onglets "tabs" grâce aux API correspondantes, ce n'est pas le cas pour les "applications" attachées à des domaines.

    Voici donc la proposition que je formule et que je résume ici :

    window.open("","name1","check=yes") retournerait :

    - si la fenêtre "name1" existe : le handle (la reférence à l'objet fenêtre existant)
    - si la fenêtre "name1" n'existe pas : "null" (ou lieu d'en ouvrir une nouvelle)
    - en l'absence de la propriété check=yes si la fenêtre "name1" n'existe pas une nouvelle est ouverte (note : pour ma part actuellement je teste si elle est nouvelle en vérifiant que son contenu est vide et la referme si nécessaire)


    Bien cordialement

    Trebly

    _____________________________________________________________________________________________________________________
    Note 1 : Dans ce cas les algorithmes de contrôle et de nettoyage éventuel sont un peu complexes, mais tout à fait maitrisables. Il peuvent aisément être encapsulés dans un nouvel objet. Les données concernant les fenêtres ouvertes sont stockées dans un cookie de domaine qui est lu et surtout réécrit quand un changement intervient par la fenêtre qui a le focus.
    _____________________________________________________________________________________________________________________
    Note 2 : Pour gérer les doublons de fenêtres (par exemple ne pas ouvrir n fois l'index ou la bibliographie attachée à un document), je nomme toute fenêtre résultant d'une requête en utilisant window.name=name; Préalablement je teste (je suis obligé de) qu'il n'y a pas de fenêtre portant ce nom. Pour cela j'utilise window.open('',<name>). Cependant comme sans paramètre window.open ouvre par défaut un onglet, le test d'existence d'une fenêtre perturbe alors considérablement l'affichage, donc je lance l'instruction avec un paramètre ce qui ouvre si elle n'existe pas une fenêtre popup que je referme immédiatement. Ce n'est pas bien beau mais ça marche et surtout j'affiche un message d'attente...
    Dans le cas de doublon pour la même url (ouvert par une autre session du site) suivant le cas :
    • L'ouverture après alerte est refusée, on bascule vers la fenêtre existante (focus()) et l'on ferme le doublon.
    • L'ouverture est acceptée avec une alerte à l'utilisateur sur les risques éventuels (mais cela permet de consulter un même texte par exemple en deux points différents).

    _____________________________________________________________________________________________________________________
    Note 3 : Il me semble que sur le plan du développement une telle évolution serait très aisée à réaliser et légère et assure la compatibilité ascendante.
    _____________________________________________________________________________________________________________________
    Note 4 : La raison de la disposition actuelle a été me semble-t-il de dire que si l'on nommait un popup en renvoyant la référence existante, si la commande de création était répétée, on évitait la création de doublon, mais ceci à partir du seul cas de filiation ("dependent" paramètre option de window.open qui à des chances d'être abandonné...). La question n'a probablement pas été posée bien plus loin. Le problème devient sérieux à partir du moment où l'on gère des données, il ne l'est pas dans les cas de simples affichages bien que souvent gênant.

  11. #11
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Voir : https://developer.mozilla.org/fr/doc...PI/Window/open


    var windowObjectReference = window.open(strUrl, strWindowName[, strWindowFeatures]);.

    Si strUrl est une chaîne vide, une nouvelle fenêtre vide de tout contenu (l'URL about:blank sera chargée) est créée avec les barres d'outils par défaut de la fenêtre principale.
    Donc votre code window.open("","name") devrait logiquement toujours ouvrir une nouvelle fenêtre.

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Le code "window.open("","name") ouvre la fenêtre name si elle existe sinon une nouvelle vierge... et...
    Bonjour,

    Je ne comprend pas ta remarque.

    Le code "window.open("","name") renvoie le handle de la fenêtre de nom "name" si elle existe (définie dans le domaine) en ignorant l'url sinon une nouvelle vierge.

    Et, dans tous le cas sauf un, la commande renvoie le handle (en js on oublie souvent que l'on manipule le plus souvent des pointeurs) de la fenêtre.
    L'exception du retour "null" se produit lorsque le domaine n'a pas le droit de créer une fenêtre (ce qui fournit un outil de test de ce droit, d'ailleurs).

    Ce que je propose c'est l'ouverture d'un deuxième cas de retour null : si un nouveau paramètre "check=yes" est indiqué et que la fenêtre n'existe pas (encore).

    Ce qui n'est pas mis en évidence est que la "fenêtre" créée par la commande est :
    • un onglet si aucun paramètre n'est donné, et
    • sinon un pop-up répondant au paramètres donnés dans ce window.open("","name","params")



    Tout cela est très clair, et mon expérience y correspond très exactement, dans : https://developer.mozilla.org/fr/doc...PI/Window/open

    Cordialement

    Trebly
    ______________________________________________________________________________________________________________
    note 1 : Résumé des cas d'affectation de "name" à une fenêtre :

    1- Les commandes qui affectent les "name" associés à des fenêtres sont :

    1. Window.open("url ou chaine vide","name","paramètres ou chaine vide") -> ouvre la première fenêtre existante (dernière créée) portant le nom dans le domaine. Si aucune autre commande n'est utilisée cela assure l'unicité des name dans un domaine, mais ce n'est pas toujours le cas.
    2. Dans le script associé à une fenêtre : window.name = "name" (string) -> cela affecte le nom "name" à la fenêtre (première affectation ou changement) ->
      • si une fenêtre du même nom existe elle le garde mais la première est cachée par la nouvelle (window.open("","name") renverra pour tout le domaine la dernière fenêtre nommée ou renommée avec le nom défini. Si la fenêtre courante est détruite la précédente réapparaitra en réponse à une commande window.open("","name").
      • si "name"="" la fenêtre perd son nom. Mais si il lui est ensuite rendu, la commande "window.open"","name") renverra le handle correct. (Ce qui semble prouver qu'il n'y a pas de lien mais simplement une recherche du name dans la pile des "tabs")
    3. La duplication par des scripts de plugins qui manipulent les onglets via les API "tabs" avec les droits d'accès associés. La duplication d'un onglet copie tout l'objet window avec le name et crée un doublon (peu importe il sont parfaitement identiques au départ, mais ensuite cela peut se gâter évidemment).
    4. Des plugins qui peuvent renommer des fenêtres


    Conséquence et discussion :
    Une fenêtre qui est ouverte à la suite d'une requête peut se nommer elle-même. Aussi dans ce cas, dans un domaine donné, toute fenêtre peut savoir grâce à window.open si une soeur donnée a été ou non déjà créée.
    Cela permet d'éviter lors de l'exécution de liens non gérés ou externes que des doublons d'url ne soient ouverts. En effet un lien de type A ( tag A et href) ouvrira (suivant le target) toujours une nouvelle fenêtre ou bien provoquera le changement d'url de la fenêtre courante ou enfin son rechargement.
    Si le développeur a soin d'assurer l'association univoque d'une url à un name, il pourra gérer l'unicité. Ainsi, si la fenêtre après son ouverture vérifie que le nom qu'elle va normalement porter est ou non déjà utilisé, il sera possible de décider (le soft ou l'utilisateur) de créer un "duplicata" portant un nom différent (mais avec un même nom de base pour la clarté). Il pourra ainsi les distinguer. Cela suppose évidemment que le même script de gestion est porté et donc comme partagé (mais pas avec les mêmes données courantes) par toutes les fenêtres d'un domaine.

    Une importante question qui est derrière est que la commande window.open("url","name") - visant à créer une nouvelle fenêtre "name" avec l'url indiquée créera cette fenêtre si le name n'existe pas, si non elle affectera l'url à la fenêtre existante, ceci en conservant les paramètres de la fenêtre si elle existe et ignorant ceux qui seraient indiqués dans la commande. Sans vérification il y a risque de détruire le contenu d'une fenêtre sur laquelle l'utilisateur est en train de travailler simultanément... d'où l'utilité de pouvoir vérifier son existence (une autre mesure est de protéger les fenêtres par un évènement "on unload", une sécurité mais moins efficace).
    Il faut noter aussi que le concepteur d'application n'a pas accès à l'url des fenêtres que son application a créé sauf s'il conserve ces données dans un objet qu'il gère lui-même. Cet objet peut être stocké en cookie de domaine (ou en données locales) et donc accessible au script commun. Ce script est alors garant de la synchronisation des actions de fenêtres d'un domaine.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Réponse plus brève pour window.open sur l'ouverture avec url='"" ou non et des paramètres ou non
    Citation Envoyé par danielhagnoul Voir le message
    Voir : https://developer.mozilla.org/fr/doc...PI/Window/open



    Donc votre code window.open("","name") devrait logiquement toujours ouvrir une nouvelle fenêtre.
    Non si "name" existe window.open("","name") renvoie un handle sur la fenêtre existante.

    Ce n'est que si elle n'existe pas que window.open("","name") ouvre logiquement toujours une nouvelle fenêtre.

    D'accord, pas d'accord, merci de me le signaler.

    Cordialement

    Trebly

    ___________________________________________________________________________________________________________________
    Quelques détails de comportement de window.open
    note 1 : si on indique des paramètres une fenêtre popup sera ouverte, sinon dans les navigateurs actuels (suivant paramètrage avec "_blank" on ouvre un onglet vide.

    note 2 : si l'on relance la commande avec une ouverture interrogative mais avec un url : window.open("url","name")alors on va peupler la fenêtre ou l'onglet précédemment créé. (dans cette deuxième exécution sur une fenêtre existante tout paramètre sera ignoré)

    note 3 : si la fenêtre existe window.open("","name") et que son contenu existe non vide (multiples test possibles) alors une commande window.open("url","name") soit provoquera le reload (url identique), soit changera le contenu en rempaçant par un load avec le nouvelle url.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Points : 63
    Points
    63
    Par défaut Tester si mon application a ouvert ou non une fenêtre "nommée" : une solution ?
    Bonsoir,

    Une question que je me pose depuis longtemps, et pour laquelle je n'ai pas de réponse technique valable est :

    Comment une application, qui n'est pas un plugin, peut-elle gérer efficacement l'ensemble des fenêtres qu'elle peut ouvrir dans un navigateur ? (en toutes circonstances)

    Confronté à cette question depuis plus d'un an, en échec, je n'ai pas trouvé de réponse valable.

    Je propose ici une solution, mais avant je parle de la nécessité et de l'utilité de résoudre cette question. En notes quelques exemples et références.

    En résumé une fonction efficace pour une application (associée à un domaine) pour tester si elle (l'une des ses fenêtres) a déjà ou non ouvert une fenêtre(ou la possibilité de l'écrire): ça n'existe pas.

    Pour mener à bien cette tâche qui est de gérer efficacement l'ensemble des fenêtres il est nécessaire, si l'on veut pouvoir maintenir la cohérence de données saisies, quand il y a lieu, non seulement de pouvoir nommer les fenêtres ouvertes ( window.open : -> onglets ou pop-up), ceci bien évidemment en respectant des règles strictes, mais aussi de pouvoir vérifier si elles existent ou non.


    L'objectif :

    Pour un domaine+port, l'objectif est que quoiqu'il arrive on puisse maintenir l'unicité de fenêtres ouvertes correspondant à une url principale (domaine + query), identifiée par "name" (hors hash) et accessible via window.open('',"name").

    En résumé, pouvoir disposer, pour toute fenêtre ouverte par mon domaine, quoi qu'il arrive, d'un tableau qui établi une relation bi-univoque entre les url (hors hash) et les noms que mon application leur aura donnée.

    Il faut tout de suite repréciser que l'application, contrairement à un plugin, ne peut pas accéder aux url des fenêtres si elle n'a pas de handle sur la(les) fenêtres et que le seul moyen pour les obtenir est l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    w=window.open('',<nom existant connu>);
    .
    C'est de là que provient la nécessité de maintenir une liste des noms avec une relation bi-univoque avec les fenêtres existantes, générées par mon application, quels que soient les évènements.

    On pourrait penser que si l'on tient à jour un tableau des créations et fermetures voulues écrit dans un cookie (pour le partager dans le domaine), on va s'en sortir, mais non !...

    Le problème posé provient de deux difficultés majeures :
    • deux sessions différentes d'un même domaine peuvent ouvrir des fenêtres de même nom. Ces fenêtres se masquent mutuellement.
    • tester si une fenêtre a déjà été ouverte nécessite d'ouvrir une fenêtre vide quand elle n'existe pas, obligatoirement la créer, ceci pour la détruire immédiatement après si elle est nouvelle. Et toute erreur est irrécupérable.


    Exposé détaillé des problèmes posés, exemples:

    Si indépendamment des noms qui sont un outil d'identification il existe des doublons affichés, l'utilisateur peut avoir ouvert plusieurs fenêtres de modification de même objet (ex: un post dans Wordpress en cours de modification dans deux fenêtres) entrainant un conflit et des pertes de données bien évidemment.

    Les "noms" devraient permettre normalement d'éviter ce problème. Mais ça ne marche pas à tous les coups, en effet quand on ouvre deux fois la même url (en créant ainsi une nouvelle session) et que la fenêtre se nomme elle-même du même nom, un faux doublon se crée. Faux parce que la première créée devient inaccessible tant que la deuxième n'est pas détruite (il n'y a pas destruction de lien mais on ne trouve que le dernier objet créé dans la pile du même nom avec l'équivalent d'un FIFO - fisrt-in-first-out).
    Le problème majeur est que seul le cas de l'ouverture via window.open garantit normalement l'unicité... de la création, malheureusement seulement dans une même session.
    Il faut donc pratiquement renommer une fenêtre pour savoir si elle n'en cache pas une autre du même nom.
    Les plugins de duplication d'onglets posent le même problème.
    La destruction intempestive pose aussi des problèmes de cohérence en perte d'information ou bien en faisant réapparaitre un doublon oublié par exemple.

    La parade

    Pour parer à ce problème je n'ai trouvé qu'un seul moyen : pouvoir tester si une fenêtre d'un nom donné existe ou non.
    A mon avis, confronté à cette question et un an de recul, c'est là un point essentiel que de pouvoir tester, avant d'ouvrir ou de nommer une fenêtre (window.name='name1'), s'il existe déjà une fenêtre du même nom (qui pourra être masquée si l'on ne prend pas garde).
    Nota : Pour maintenir l'unicité des noms quand un doublon d'url est autorisé (afficher plusieurs fois le même document) le nom courant peut-être modifié pour chaque instance avec un même nom de "base" (i.e. un N° d'instance est ajouté au nom de "base de famille" associé de manière univoque à l'url).


    Or, pour ce faire, il n'y a aujourd'hui qu'une seule et unique méthode : voir si window.open("","name") renvoie un handle vers une fenêtre ou bien ouvre une fenêtre vide.

    C'est malheureusement lourd et très couteux en ressources quand la fenêtre n'existe pas et parfois bloquant voire inapplicable.

    Je ne comprend pas qu'une telle possibilité n'existe pas et je ne vois pas, a priori, de problème de sécurité que cela poserait (à condition de respecter des règles de nommage résistant à des tentatives de piratage par des moyens ad-hoc).

    Ce problème est traité pour les plugins qui accèdent à la gestion des onglets "tabs" grâce aux API correspondantes, ce n'est pas le cas pour les "applications" attachées à des domaines.

    Voici donc la proposition que je formule et que je résume ici :

    window.open("","name1","check=yes") retournerait :

    • - si la fenêtre "name1" existe : le handle (la reférence à l'objet fenêtre existant)
    • - si la fenêtre "name1" n'existe pas : "null" (ou lieu d'en ouvrir une nouvelle)
    • - en l'absence de la propriété check=yes si la fenêtre "name1" n'existe pas une nouvelle est ouverte
    • (note : pour ma part actuellement je teste si elle est nouvelle en vérifiant que son contenu est vide et la referme si nécessaire, sinon je la peuple)



    Qu'en pensez-vous ?


    Bien cordialement

    Trebly

    _____________________________________________________________________________________________________________
    Note 1 : Dans ce cas les algorithmes de contrôle et de nettoyage éventuel sont un peu complexes, mais tout à fait maitrisables. Il peuvent aisément être encapsulés dans un nouvel objet. Les données concernant les fenêtres ouvertes sont stockées dans un cookie de domaine qui est lu et surtout réécrit quand un changement intervient par la fenêtre qui a le focus.
    _____________________________________________________________________________________________________________
    Note 2 : Pour gérer les doublons de fenêtres (par exemple ne pas ouvrir n fois l'index ou la bibliographie attachée à un document), je nomme toute fenêtre résultant d'une requête en utilisant window.name=name; Préalablement je teste (je suis obligé de) qu'il n'y a pas de fenêtre portant ce nom. Pour cela j'utilise window.open('',<name>). Cependant comme sans paramètre window.open ouvre par défaut un onglet, le test d'existence d'une fenêtre perturbe alors considérablement l'affichage, donc je lance l'instruction avec un paramètre ce qui ouvre si elle n'existe pas une fenêtre popup que je referme immédiatement. Ce n'est pas bien beau mais ça marche et surtout j'affiche un message d'attente...
    Dans le cas de doublon pour la même url (ouvert par une autre session du site) suivant le cas :
    • L'ouverture après alerte est refusée, on bascule vers la fenêtre existante (focus()) et l'on ferme le doublon.
    • L'ouverture est acceptée avec une alerte à l'utilisateur sur les risques éventuels (mais cela permet de consulter un même texte par exemple en deux points différents).

    ______________________________________________________________________________________________________________
    Note 3 : Il me semble que sur le plan du développement une telle évolution serait très aisée à réaliser et légère et assure la compatibilité ascendante.
    ______________________________________________________________________________________________________________
    Note 4 : La raison de la disposition actuelle a été me semble-t-il de dire que si l'on nommait un popup en renvoyant la référence existante, si la commande de création était répétée, on évitait la création de doublon, mais ceci à partir du seul cas de filiation ("dependent" paramètre option de window.open qui à des chances d'être abandonné..., et de l'attribut de fenêtre : "opener" qui permet d'atteindre la parent - ce qui peut poser des problèmes de sécurité d'ailleurs). La question n'a probablement pas été posée bien plus loin. Le problème devient sérieux à partir du moment où l'on gère des données, il ne l'est pas dans les cas de simples affichages bien que souvent gênant.

Discussions similaires

  1. [WD12] Accéder à une fenêtre MDI par son alias
    Par Bowen dans le forum WinDev
    Réponses: 2
    Dernier message: 19/05/2008, 18h08
  2. [ SWING ] Ouvrir une fenêtre dans son parent
    Par Invité dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 12/01/2006, 16h12
  3. Accéder à une propriété par son nom
    Par Neilos dans le forum C++Builder
    Réponses: 5
    Dernier message: 22/09/2005, 21h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo