Link em negrito onde ninguém havia vinculado antes: fragmentos de texto

Fragmentos de texto permitem especificar um snippet de texto no fragmento de URL. Ao navegar para um URL com esse fragmento de texto, o navegador pode enfatizar e/ou a chamar a atenção do usuário.

Identificadores de fragmento

O Chrome 80 foi um grande lançamento. Ele continha vários recursos muito esperados, como Módulos ECMAScript em Web Workers, uma coalescência nula, encadeamento opcional e muito mais. Como sempre, o lançamento anunciada por um postagem do blog na Blog do Chromium. Confira um trecho da postagem do blog na captura de tela abaixo.

Postagem do blog do Chromium com caixas vermelhas ao redor de elementos com um atributo id.

Você provavelmente está se perguntando o que significam as caixas vermelhas. Elas são o resultado da execução snippet a seguir no DevTools. Ele destaca todos os elementos que têm um atributo id.

document.querySelectorAll('[id]').forEach((el) => {
  el.style.border = 'solid 2px red';
});

Posso colocar um link direto para qualquer elemento destacado com uma caixa vermelha graças à identificador de fragmentos que eu uso no hash da para o URL de sua página. Supondo que eu queira criar um link direto para a página Envie feedback em nossa na caixa Fóruns de produtos de lado, eu poderia fazer isso criando o URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1 Como é possível observar no painel "Elementos" das Ferramentas para desenvolvedores, o elemento em questão tem um id. com o valor HTML1.

Ferramentas para desenvolvedores mostrando o id de um elemento.

Se eu analisar esse URL com o construtor URL() do JavaScript, os diferentes componentes serão revelados. Observe a propriedade hash com o valor #HTML1.

new URL('https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1');
/* Creates a new `URL` object
URL {
  hash: "#HTML1"
  host: "blog.chromium.org"
  hostname: "blog.chromium.org"
  href: "https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1"
  origin: "https://blog.chromium.org"
  password: ""
  pathname: "/2019/12/chrome-80-content-indexing-es-modules.html"
  port: ""
  protocol: "https:"
  search: ""
  searchParams: URLSearchParams {}
  username: ""
}
*/

O fato de eu ter que abrir as Ferramentas para desenvolvedores para encontrar o id de um elemento diz muito sobre a probabilidade de que esta seção específica da página fosse vinculada pelo autor do a postagem do blog.

E se eu quiser vincular a um site sem id? Digamos que eu queira criar um link para os módulos ECMAScript no título "Web Workers". Como mostrado na captura de tela abaixo, o <h1> em questão não têm um atributo id, o que significa que não é possível vincular a esse cabeçalho. Esse é o problema que Fragmentos de texto resolvem.

Ferramentas para desenvolvedores mostrando um cabeçalho sem um id.

Fragmentos de texto

A proposta Fragmentos de texto adiciona suporte para especificando um snippet de texto no hash do URL. Ao navegar para um URL com esse fragmento de texto, o o user agent pode enfatizar e/ou chamar a atenção do usuário.

Compatibilidade com navegadores

Compatibilidade com navegadores

  • Chrome: 89.
  • Borda: 89.
  • Firefox: incompatível.
  • Safari: incompatível.

Origem

Por motivos de segurança, o recurso exige que os links sejam abertos em um Contexto noopener. Portanto, inclua rel="noopener" na sua <a> marcação de âncora ou adicionar noopener para sua Window.open() lista de recursos de funcionalidade de janela.

start

Na forma mais simples, a sintaxe dos fragmentos de texto é a seguinte: o símbolo de hash # seguido por :~:text= e, por fim, start, que representa codificado por porcentagem texto para o qual quero criar um link.

#:~:text=start

Por exemplo, digamos que eu queira criar um link para o cabeçalho Módulos ECMAScript em Web Workers na postagem do blog anunciando os recursos do Chrome 80, neste caso, o URL será:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers

O fragmento de texto é enfatizado desta maneira. Se você clicar no link em um navegador compatível, como o Chrome, o fragmento de texto será destacado e rola até a visualização:

Fragmento de texto rolado para a visualização e destacado.

start e end

E se eu quiser vincular a seção inteira intitulada Módulos ECMAScript nos Web Workers, não apenas o cabeçalho? A codificação por porcentagem de todo o texto da seção tornaria o URL resultante muito longa.

Felizmente existe uma maneira melhor. Em vez de o texto inteiro, eu posso enquadrar o texto desejado usando a Sintaxe start,end. Por isso, especifico algumas palavras codificadas por porcentagem no início do texto desejado e algumas palavras codificadas por porcentagem no final do texto desejado, separadas por uma vírgula ,.

Ela tem esta aparência:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers,ES%20Modules%20in%20Web%20Workers..

Para start, tenho ECMAScript%20Modules%20in%20Web%20Workers, depois uma vírgula , por ES%20Modules%20in%20Web%20Workers. como end. Quando você clica em um navegador compatível como o Chrome, a seção inteira é destacada e rolada para visualização:

Fragmento de texto rolado para a visualização e destacado.

Agora você pode se perguntar sobre minhas escolhas de start e end. O URL um pouco mais curto https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers. com apenas duas palavras de cada lado também teria funcionado. Compare start e end com a valores anteriores.

Se eu avançar e usar apenas uma palavra para start e end, será possível que estou com problemas. O URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript,Workers. agora é ainda mais curto, mas o fragmento de texto destacado não é mais o pretendido originalmente. O o destaque pára na primeira ocorrência da palavra Workers., que é o correto, mas não o que eu pretende destacar. O problema é que a seção desejada não é identificada de forma exclusiva pelas valores atuais de start e end de uma palavra:

Fragmento de texto não intencional rolado para a visualização e destacado.

prefix- e -suffix

Usar valores longos o suficiente para start e end é uma solução para conseguir um link exclusivo. Em algumas situações, no entanto, isso não é possível. Além disso, por que escolhi o Postagem do blog sobre o lançamento do Chrome 80 como meu exemplo? A resposta é que, nesta versão, Fragments de texto foram introduzidos:

Texto da postagem do blog: Fragmentos do URL do texto. Usuários ou autores agora podem criar links para uma parte específica de uma página usando um fragmento de texto fornecido em um URL. Quando a página é carregada, o navegador destaca o texto e rola o fragmento para que ele apareça. Por exemplo, o URL abaixo carrega uma página wiki para &quot;Gato&quot; e rola até o conteúdo listado no parâmetro `text`.
Trecho da postagem do blog sobre o anúncio de fragmentos de texto.

Observe como, na captura de tela acima da palavra "texto", quatro vezes. A quarta ocorrência escritas em fonte verde. Se eu quisesse criar um link para essa palavra específica, definiria start para text. Como a palavra "texto" é apenas uma palavra, não pode haver end. E agora? O URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text corresponde à primeira ocorrência da palavra "Text" já está no título:

Fragmento de texto correspondente na primeira ocorrência de "Text".
.

Felizmente existe uma solução. Em casos como esse, posso especificar um prefix​- e um -suffix. O palavra antes da fonte de código verde "text" é "o" e a palavra depois é "parâmetro". Nenhuma das opções outras três ocorrências da palavra "texto" tenham as mesmas palavras ao redor. Armado com este conhecimento, posso ajustar o URL anterior e adicionar o prefix- e o -suffix. Como o outro , eles também precisam ser codificados por porcentagem e podem conter mais de uma palavra. https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=the-,text,-parameter. Para permitir que o analisador identifique claramente o prefix- e o -suffix, eles precisam ser separados do start e a end opcional com um traço -.

Fragmento de texto correspondente à ocorrência desejada de "text".

A sintaxe completa

A sintaxe completa dos fragmentos de texto é mostrada abaixo. Os colchetes indicam um parâmetro opcional. Os valores de todos os parâmetros precisam ser codificados por porcentagem. Isso é especialmente importante para o traço caracteres -, e comercial & e vírgula ,, portanto, não são interpretados como parte do texto sintaxe da diretiva.

#:~:text=[prefix-,]start[,end][,-suffix]

Cada um de prefix-, start, end e -suffix corresponderá apenas ao texto de uma única elemento de nível de bloco, mas os intervalos start,end completos podem abranger vários blocos. Por exemplo: :~:text=The quick,lazy dog não terá correspondência no exemplo a seguir, porque o início string "The Quick" não aparece em um único elemento ininterrupto no nível do bloco:

<div>
  The
  <div></div>
  quick brown fox
</div>
<div>jumped over the lazy dog</div>

No entanto, ele corresponde a este exemplo:

<div>The quick brown fox</div>
<div>jumped over the lazy dog</div>

Como criar URLs de fragmento de texto com uma extensão de navegador

Criar URLs de fragmentos de texto manualmente é tedioso, especialmente quando se trata de garantir que eles sejam exclusivos. Se você realmente quiser, a especificação traz algumas dicas e lista o etapas para gerar URLs de fragmento de texto Nós fornecemos uma extensão de navegador de código aberto chamada Link to Text Fragment que permite a qualquer texto selecionando-o e clicando em "Copiar link para o texto selecionado" no contexto . Esta extensão está disponível para os seguintes navegadores:

.
Link para o fragmento de texto .

Vários fragmentos de texto em um URL

Vários fragmentos de texto podem aparecer em um URL. Os fragmentos de texto específicos precisam ser separadas por um caractere E comercial &. Confira um exemplo de link com três fragmentos de texto: https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=Text%20URL%20Fragments&text=text,-parameter&text=:~:text=On%20islands,%20birds%20can%20contribute%20as%20much%20as%2060%25%20of%20a%20cat's%20diet

Três fragmentos de texto em um URL.

Misturando fragmentos de elementos e texto

Os fragmentos de elementos tradicionais podem ser combinados com fragmentos de texto. É perfeitamente normal ter ambos no mesmo URL, por exemplo, para fornecer uma substituição significativa caso o texto original na página muda, para que o fragmento de texto não corresponda mais. O URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1:~:text=Give%20us%20feedback%20in%20our%20Product%20Forums. vinculando para a seção Envie feedback em nossa Seção Fóruns de produto contém um fragmento de elemento (HTML1) e um fragmento de texto (text=Give%20us%20feedback%20in%20our%20Product%20Forums.):

Vinculação com fragmento de elemento e fragmento de texto
.

A diretiva de fragmento

Há um elemento da sintaxe que ainda não expliquei: a diretiva de fragmento :~:. Para evitar problemas de compatibilidade com fragmentos de elementos de URL existentes, como mostrado acima, os A especificação Text Fragments introduz o fragmento diretiva. A diretiva de fragmento é uma parte do fragmento de URL delimitada pela sequência de código :~:: Ele é reservado para instruções do user agent, como text=, e é removido do URL durante o carregamento para que os scripts do autor não possam interagir diretamente com ele. As instruções do user agent são também chamados de diretivas. No caso concreto, a text= é chamada de diretiva de texto.

Detecção de recursos

Para detectar compatibilidade, teste a propriedade somente leitura fragmentDirective em document. O fragmento é um mecanismo para que os URLs especifiquem instruções direcionadas ao navegador, em vez da diretiva documento. Ele se destina a evitar a interação direta com o script do autor, para que o futuro user agent instruções podem ser adicionadas sem medo de introduzir alterações interruptivas no conteúdo existente. Um possíveis exemplos de futuras adições poderiam ser as dicas de tradução.

if ('fragmentDirective' in document) {
  // Text Fragments is supported.
}

A detecção de recursos é destinada principalmente a casos em que os links são gerados dinamicamente (por exemplo, mecanismos de pesquisa) para evitar a disponibilização de links de fragmentos de texto para navegadores que não são compatíveis com eles.

Como definir o estilo de fragmentos de texto

Por padrão, os navegadores estilizam os fragmentos de texto da mesma forma mark (normalmente preto sobre amarelo, as cores do sistema CSS para mark). A folha de estilo do user agent contém um CSS semelhante a este:

:root::target-text {
  color: MarkText;
  background: Mark;
}

Como você pode ver, o navegador expõe um pseudosseletor ::target-text que você pode usar personalizar o destaque aplicado. Por exemplo, é possível projetar os fragmentos de texto para serem pretos em um fundo vermelho. Como sempre, não se esqueça de Verificar o contraste de cores para que o estilo de substituição não cause problemas de acessibilidade e verifique se o destaque realmente se destaca visualmente do restante do conteúdo.

:root::target-text {
  color: black;
  background-color: red;
}

Capacidade de polivalidade

Até certo ponto, o recurso de fragmentos de texto pode ter polyfill aplicado. Oferecemos um polyfill, que é usado internamente por a extensão para navegadores que não fornecem suporte integrado para fragmentos de texto em que a funcionalidade é implementada em JavaScript.

O polyfill contém um arquivo fragment-generation-utils.js que você pode importar e usar para gerar links de fragmentos de texto. Isso é descritos no exemplo de código abaixo:

const { generateFragment } = await import('https://unpkg.com/text-fragments-polyfill/dist/fragment-generation-utils.js');
const result = generateFragment(window.getSelection());
if (result.status === 0) {
  let url = `${location.origin}${location.pathname}${location.search}`;
  const fragment = result.fragment;
  const prefix = fragment.prefix ?
    `${encodeURIComponent(fragment.prefix)}-,` :
    '';
  const suffix = fragment.suffix ?
    `,-${encodeURIComponent(fragment.suffix)}` :
    '';
  const start = encodeURIComponent(fragment.textStart);
  const end = fragment.textEnd ?
    `,${encodeURIComponent(fragment.textEnd)}` :
    '';
  url += `#:~:text=${prefix}${start}${end}${suffix}`;
  console.log(url);
}

Extrair fragmentos de texto para análise

Muitos sites usam o fragmento para roteamento. É por isso que os navegadores removem os fragmentos de texto para não corromper essas páginas. Há um necessidade confirmada para expor links de fragmentos de texto para páginas, por exemplo, para fins de análise, mas a solução proposta ainda não foi implementada. Como solução alternativa, use o código abaixo para extrair as informações desejadas.

new URL(performance.getEntries().find(({ type }) => type === 'navigate').name).hash;

Segurança

As diretivas de fragmento de texto são invocadas somente em navegações completas (que não sejam da mesma página) que sejam resultado de a ativação de usuários. Além disso, as navegações com origem em uma origem diferente do destino exigirão o a navegação ocorra em um Contexto noopener, como que a página de destino seja suficientemente isolada. As diretivas de fragmento de texto são apenas aplicada ao frame principal. Isso significa que o texto não será pesquisado dentro de iframes, e o iframe a navegação não vai invocar um fragmento de texto.

Privacidade

É importante que as implementações da especificação de fragmentos de texto não vazem se um texto fragmento foi encontrado em uma página ou não. Embora os fragmentos de elementos estejam totalmente sob o controle autor da página original, os fragmentos de texto podem ser criados por qualquer pessoa. Lembra como no meu exemplo acima não havia como vincular o cabeçalho Módulos ECMAScript in Web Workers, já que <h1> não têm um id, mas é possível criar links para qualquer pessoa, inclusive eu, com uma criação o fragmento de texto?

Imagine que eu gerenciasse uma rede de publicidade mal-intencionada evil-ads.example.com. Imagine também que, em um dos meus anúncios Iframes eu criei dinamicamente um iframe de origem cruzada oculto para dating.example.com com um texto URL do fragmento dating.example.com#:~:text=Log%20Out quando o usuário interagir com o anúncio. Se o texto "Sair" foi encontrado, sei que a vítima está conectado ao dating.example.com, que pode ser usado para criar perfis de usuários. Como um Text simples A implementação de fragmentos pode decidir que uma correspondência bem-sucedida deve causar uma chave de foco, evil-ads.example.com Posso detectar o evento blur e saber quando ocorre uma correspondência. Em No Chrome, implementamos fragmentos de texto de forma que o cenário acima não possa acontecer.

Outro ataque pode ser explorar o tráfego de rede com base na posição de rolagem. Suponha que eu tenha acesso a registros de tráfego de rede da vítima, por exemplo, como administrador da intranet de uma empresa. Agora imagine havia um documento de recursos humanos longo What to Do if You Suffer From..., além de uma lista de condições como esgotamento, ansiedade etc. Posso colocar um pixel de rastreamento ao lado de cada item na lista. Se eu determinar que o carregamento temporal do documento ocorre com o carregamento do pixel de rastreamento ao lado do item esgotado, como administrador da intranet, posso determinar um funcionário clicou em um link de fragmento de texto com :~:text=burn%20out que o funcionário pode ter considerado confidencial e não visível para ninguém. Como este exemplo é um pouco inventado para começar e já que sua exploração exige pré-condições muito específicas para ser cumprida, a equipe de segurança do Chrome avaliou o risco de implementar a rolagem na navegação para facilitar o gerenciamento. Outros user agents podem decidir mostrar um elemento da interface de rolagem manual.

Para os sites que desejam desativar, o Chromium suporta uma Política de documentos valor de cabeçalho que eles podem enviar para que os user agents não processem URLs de fragmento de texto.

Document-Policy: force-load-at-top

Como desativar fragmentos de texto

A maneira mais fácil de desativar o recurso é usando uma extensão que possa injetar uma resposta HTTP cabeçalhos, por exemplo, ModHeader (não é um produto do Google) para inserir um cabeçalho de resposta (não solicitação) da seguinte forma:

Document-Policy: force-load-at-top

Outra forma mais complexa de recusar é usar a configuração empresarial ScrollToTextFragmentEnabled Para fazer isso no macOS, cole o comando abaixo no terminal.

defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false

No Windows, siga a documentação Suporte da Ajuda do Google Chrome Enterprise site.

Para algumas pesquisas, o mecanismo de pesquisa do Google fornece uma resposta rápida ou um resumo com um conteúdo snippet de um site relevante. Estes trechos em destaque têm maior probabilidade de aparecer quando uma pesquisa na forma de uma pergunta. Clicar em um trecho em destaque leva o usuário diretamente para a página em destaque do snippet de código na página da Web de origem. Isso funciona graças aos URLs de fragmentos de texto criados automaticamente.

Página de resultados do mecanismo de pesquisa do Google mostrando um trecho em destaque. A barra de status mostra o URL dos fragmentos de texto.
.
Depois de clicar, a seção relevante da página é exibida na tela.

Conclusão

O URL de fragmentos de texto é um recurso avançado para criar links para texto arbitrário em páginas da Web. O acadêmico pode usá-lo para fornecer citações altamente precisas ou links de referência. Os mecanismos de pesquisa podem usar até o link direto para os resultados de texto nas páginas. Sites de redes sociais podem usá-lo para permitir que os usuários compartilhem trechos específicos de uma página da Web, em vez de capturas de tela inacessíveis. Espero que você comece Como usar URLs de fragmento de texto e considerá-las tão úteis quanto eu. Instale o Navegador Link para fragmento de texto .

Agradecimentos

Os fragmentos de texto foram implementados e especificados por Nick Burris e David Bokan, com contribuições de Conceder Wang. Agradecemos a Joe Medley por a análise completa deste artigo. Imagem principal de Greg Rakozy no Abrir a página.