PageSourceSearch

https://www.swift.org/assets/javascripts/new-javascripts/blog.js

js swift.org collected 2026-10-01 06:58:49 UTC 3,475 bytes, 111 lines download raw bytes

1const wrapper = document.querySelector('.blogs-and-filter-wrapper')
2const postsWrapper = wrapper.querySelector('.blogs-wrapper')
3const postData = JSON.parse(wrapper.querySelector('#post-data').textContent)
4const filters = [...wrapper.querySelectorAll('.category-filter')]
5const selectAllBox = document.querySelector('.select-all')
6const dropdown = document.querySelector('.dropdown')
7const allCheckboxes = [selectAllBox, ...filters]
8const filterMenuToggle = document.querySelector('.dropdown-toggle')
9
10// create post links
11const createAnchor = (postData) => {
12  const anchor = document.createElement('a')
13  anchor.href = postData.url
14  anchor.classList = 'post-link'
15  anchor.innerHTML = `
16    <h3 class="title-4">${postData.title}</h3>
17    <time pubdate datetime="${postData.date}" class="blog-date body">${postData.date}</time>
18    <p class="body">${postData.excerpt}</p>
19    ${postData.categories.reduce((markup, category) => {
20      return markup + ` <span class="category body">${category}</span>`
21    }, '')}
22    `
23  return anchor
24}
25
26// checks all filters
27const selectAllCategories = (selectAllBox, checkboxes) => {
28  if (selectAllBox.checked) {
29    checkboxes.forEach((checkbox) => {
30      checkbox.checked = true
31    })
32
33    updatePosts(filterPosts(elementsCache, checkboxes), postsWrapper)
34  }
35}
36
37const filterPosts = (elementsCache, checkboxes) => {
38  // If all categories are selected, bypass filter check
39  if (selectAllBox.checked) return elementsCache
40
41  const activeFilters = checkboxes
42    .filter((checkbox) => checkbox.checked)
43    .map((checkbox) => checkbox.value)
44  const filteredPosts = elementsCache.filter((post) => {
45    return post.data.categories.some((category) => {
46      return activeFilters.includes(category)
47    })
48  })
49
50  return filteredPosts
51}
52
53const updatePosts = (posts, postsWrapper) => {
54  postsWrapper.innerHTML = ''
55  for (let post of posts) {
56    postsWrapper.appendChild(post.elemenet)
57  }
58}
59
60const elementsCache = postData.map((post) => {
61  return {
62    data: post,
63    elemenet: createAnchor(post),
64  }
65})
66
67updatePosts(filterPosts(elementsCache, filters), postsWrapper, postsWrapper)
68
69filterMenuToggle.addEventListener('click', () => {
70  dropdown.classList.toggle('active')
71
72  const isExpanded = filterMenuToggle.getAttribute('aria-expanded') === 'true'
73  filterMenuToggle.toggleAttribute('aria-expanded', !isExpanded)
74})
75
76// Close the dropdown if clicked outside
77window.addEventListener('click', (evt) => {
78  if (!dropdown.contains(evt.target)) {
79    dropdown.classList.remove('active')
80    filterMenuToggle.setAttribute('aria-expanded', 'false')
81  }
82})
83
84// Select all category filters
85selectAllBox.addEventListener('click', () =>
86  selectAllCategories(selectAllBox, filters),
87)
88
89filters.forEach((checkbox) => {
90  checkbox.addEventListener('change', () => {
91    const enabledFilters = filters.filter((checkbox) => checkbox.checked)
92
93    if (enabledFilters.length === 1) {
94      enabledFilters[0].disabled = true
95    } else {
96      filters.forEach((checkbox) => (checkbox.disabled = false))
97    }
98
99    // If every box is checked, select all
100    if (enabledFilters.length === filters.length) {
101      selectAllBox.checked = true
102      selectAllBox.disabled = true
103      // Uncheck all select all if filter was unchecked
104    } else if (!checkbox.checked && selectAllBox.checked) {
105      selectAllBox.checked = false
106      selectAllBox.disabled = false
107    }
108
109    updatePosts(filterPosts(elementsCache, filters), postsWrapper)
110  })
111})

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.