faster hydrateContent() algorithm, add test (#109)
This commit is contained in:
		
							parent
							
								
									f189998a57
								
							
						
					
					
						commit
						707e89e899
					
				
					 2 changed files with 82 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -94,45 +94,42 @@
 | 
			
		|||
        if (!this.refs.node) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        mark('hydrateContent')
 | 
			
		||||
        let node = this.refs.node
 | 
			
		||||
        let originalStatus = this.get('originalStatus')
 | 
			
		||||
        let uuid = this.get('uuid')
 | 
			
		||||
        let count = 0
 | 
			
		||||
        mark('hydrateContent')
 | 
			
		||||
        if (originalStatus.tags && originalStatus.tags.length) {
 | 
			
		||||
          let anchorTags = node.querySelectorAll('a[class~=hashtag][href^=http]')
 | 
			
		||||
          for (let tag of originalStatus.tags) {
 | 
			
		||||
            for (let i = 0, len = anchorTags.length; i < len; i++) {
 | 
			
		||||
              let anchorTag = anchorTags[i]
 | 
			
		||||
              if (anchorTag.getAttribute('href').endsWith(`/tags/${tag.name}`)) {
 | 
			
		||||
                anchorTag.setAttribute('href', `/tags/${tag.name}`)
 | 
			
		||||
                anchorTag.setAttribute('focus-key', `status-content-link-${uuid}-${++count}`)
 | 
			
		||||
                anchorTag.removeAttribute('target')
 | 
			
		||||
                anchorTag.removeAttribute('rel')
 | 
			
		||||
        let anchors = node.getElementsByTagName('A')
 | 
			
		||||
        let mentions = originalStatus.mentions
 | 
			
		||||
        let tags = originalStatus.tags
 | 
			
		||||
        for (let i = 0, len = anchors.length; i < len; i++) {
 | 
			
		||||
          let anchor = anchors[i]
 | 
			
		||||
          let href = anchor.getAttribute('href')
 | 
			
		||||
          if (tags && anchor.classList.contains('hashtag')) {
 | 
			
		||||
            for (let j = 0, jLen = tags.length; j < jLen; j++) {
 | 
			
		||||
              let tag = tags[j]
 | 
			
		||||
              if (href.endsWith(`/tags/${tag.name}`)) {
 | 
			
		||||
                anchor.setAttribute('href', `/tags/${tag.name}`)
 | 
			
		||||
                anchor.setAttribute('focus-key', `status-content-link-${uuid}-${++count}`)
 | 
			
		||||
                anchor.removeAttribute('target')
 | 
			
		||||
                anchor.removeAttribute('rel')
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (originalStatus.mentions && originalStatus.mentions.length) {
 | 
			
		||||
          let anchorTags = node.querySelectorAll('a[class~=mention][href^=http]')
 | 
			
		||||
          for (let mention of originalStatus.mentions) {
 | 
			
		||||
            for (let i = 0, len = anchorTags.length; i < len; i++) {
 | 
			
		||||
              let anchorTag = anchorTags[i]
 | 
			
		||||
              if (anchorTag.getAttribute('href') === mention.url) {
 | 
			
		||||
                anchorTag.setAttribute('href', `/accounts/${mention.id}`)
 | 
			
		||||
                anchorTag.setAttribute('title', `@${mention.acct}`)
 | 
			
		||||
                anchorTag.setAttribute('focus-key', `status-content-link-${uuid}-${++count}`)
 | 
			
		||||
                anchorTag.removeAttribute('target')
 | 
			
		||||
                anchorTag.removeAttribute('rel')
 | 
			
		||||
          } else if (mentions && anchor.classList.contains('mention')) {
 | 
			
		||||
            for (let j = 0, jLen = mentions.length; j < jLen; j++) {
 | 
			
		||||
              let mention = mentions[j]
 | 
			
		||||
              if (href === mention.url) {
 | 
			
		||||
                anchor.setAttribute('href', `/accounts/${mention.id}`)
 | 
			
		||||
                anchor.setAttribute('title', `@${mention.acct}`)
 | 
			
		||||
                anchor.setAttribute('focus-key', `status-content-link-${uuid}-${++count}`)
 | 
			
		||||
                anchor.removeAttribute('target')
 | 
			
		||||
                anchor.removeAttribute('rel')
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          } else if (anchor.getAttribute('rel') === 'nofollow noopener') {
 | 
			
		||||
            anchor.setAttribute('title', href)
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        let externalLinks = node.querySelectorAll('a[rel="nofollow noopener"]')
 | 
			
		||||
        for (let i = 0, len = externalLinks.length; i < len; i++) {
 | 
			
		||||
          let link = externalLinks[i]
 | 
			
		||||
          link.setAttribute('title', link.getAttribute('href'))
 | 
			
		||||
        }
 | 
			
		||||
        stop('hydrateContent')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										56
									
								
								tests/spec/112-status-links.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								tests/spec/112-status-links.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
import {
 | 
			
		||||
  composeButton,
 | 
			
		||||
  composeInput,
 | 
			
		||||
  getNthStatus
 | 
			
		||||
} from '../utils'
 | 
			
		||||
import { foobarRole } from '../roles'
 | 
			
		||||
 | 
			
		||||
fixture`112-status-links.js`
 | 
			
		||||
  .page`http://localhost:4002`
 | 
			
		||||
 | 
			
		||||
test('External links, hashtags, and mentions have correct attributes', async t => {
 | 
			
		||||
  let text = 'Why hello there @admin and @baz and @quux ' +
 | 
			
		||||
    'and also #tag and #anotherTag and #yetAnotherTag ' +
 | 
			
		||||
    'and also http://example.com and https://joinmastodon.org and ' +
 | 
			
		||||
    'https://mastodon.social.'
 | 
			
		||||
 | 
			
		||||
  const nthAnchor = n => getNthStatus(0).find('.status-content a').nth(n)
 | 
			
		||||
 | 
			
		||||
  await t.useRole(foobarRole)
 | 
			
		||||
    .typeText(composeInput, text, {paste: true})
 | 
			
		||||
    .click(composeButton)
 | 
			
		||||
    .expect(getNthStatus(0).innerText).contains('Why hello there', {timeout: 20000})
 | 
			
		||||
    .expect(nthAnchor(0).getAttribute('href')).eql('/accounts/1')
 | 
			
		||||
    .expect(nthAnchor(0).hasAttribute('rel')).notOk()
 | 
			
		||||
    .expect(nthAnchor(0).getAttribute('title')).eql('@admin')
 | 
			
		||||
    .expect(nthAnchor(0).hasAttribute('target')).notOk()
 | 
			
		||||
    .expect(nthAnchor(1).getAttribute('href')).eql('/accounts/5')
 | 
			
		||||
    .expect(nthAnchor(1).hasAttribute('rel')).notOk()
 | 
			
		||||
    .expect(nthAnchor(1).getAttribute('title')).eql('@baz')
 | 
			
		||||
    .expect(nthAnchor(1).hasAttribute('target')).notOk()
 | 
			
		||||
    .expect(nthAnchor(2).getAttribute('href')).eql('/accounts/3')
 | 
			
		||||
    .expect(nthAnchor(2).hasAttribute('rel')).notOk()
 | 
			
		||||
    .expect(nthAnchor(2).getAttribute('title')).eql('@quux')
 | 
			
		||||
    .expect(nthAnchor(2).hasAttribute('target')).notOk()
 | 
			
		||||
    .expect(nthAnchor(3).getAttribute('href')).eql('/tags/tag')
 | 
			
		||||
    .expect(nthAnchor(3).hasAttribute('rel')).notOk()
 | 
			
		||||
    .expect(nthAnchor(3).hasAttribute('target')).notOk()
 | 
			
		||||
    .expect(nthAnchor(4).getAttribute('href')).eql('/tags/anothertag')
 | 
			
		||||
    .expect(nthAnchor(4).hasAttribute('rel')).notOk()
 | 
			
		||||
    .expect(nthAnchor(4).hasAttribute('target')).notOk()
 | 
			
		||||
    .expect(nthAnchor(5).getAttribute('href')).eql('/tags/yetanothertag')
 | 
			
		||||
    .expect(nthAnchor(5).hasAttribute('rel')).notOk()
 | 
			
		||||
    .expect(nthAnchor(5).hasAttribute('target')).notOk()
 | 
			
		||||
    .expect(nthAnchor(6).getAttribute('href')).eql('http://example.com')
 | 
			
		||||
    .expect(nthAnchor(6).getAttribute('rel')).eql('nofollow noopener')
 | 
			
		||||
    .expect(nthAnchor(6).getAttribute('title')).eql('http://example.com')
 | 
			
		||||
    .expect(nthAnchor(6).getAttribute('target')).eql('_blank')
 | 
			
		||||
    .expect(nthAnchor(7).getAttribute('href')).eql('https://joinmastodon.org')
 | 
			
		||||
    .expect(nthAnchor(7).getAttribute('rel')).eql('nofollow noopener')
 | 
			
		||||
    .expect(nthAnchor(7).getAttribute('title')).eql('https://joinmastodon.org')
 | 
			
		||||
    .expect(nthAnchor(7).getAttribute('target')).eql('_blank')
 | 
			
		||||
    .expect(nthAnchor(8).getAttribute('href')).eql('https://mastodon.social')
 | 
			
		||||
    .expect(nthAnchor(8).getAttribute('rel')).eql('nofollow noopener')
 | 
			
		||||
    .expect(nthAnchor(8).getAttribute('title')).eql('https://mastodon.social')
 | 
			
		||||
    .expect(nthAnchor(8).getAttribute('target')).eql('_blank')
 | 
			
		||||
})
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue