PageSourceSearch

https://www.ibabbleon.com/dist/vendors/autocomplete/autocomplete.js

js ibabbleon.com collected 2026-09-24 08:43:11 UTC 8,761 bytes, 196 lines download raw bytes

1const field = document.getElementById("search")
2const datasrc = [
3  { label: "App Localization Services", value: "app_localization.html", keywords: "translate internationalization l10n i18n application" },
4  { label: "iOS Localization Services", value: "ios_localization_services.html", keywords: "iphone ipad xcode Localizable stringsdict xliff xcloc siri" },
5  {
6    label: "AI translation review (MTPE)",
7    value: "ai_assisted_translation_mtpe.html",
8    keywords: "AI review claude gen generative chatgpt gpt artificial intelligence machine post editing mtpe",
9  },
10  { label: "Contact us", value: "contact.html", keywords: "Benjamin Zadik Salim Martell write message email e-mail" },
11  { label: "Our team", value: "team.html", keywords: "about translators company info" },
12  { label: "Frequently Asked Questions", value: "app-localization-faq.html", keywords: "help support" },
13  { label: "Babble Blog", value: "/blog", keywords: "news" },
14  { label: "Game Localization", value: "game_localization.html", keywords: "video console sony nintendo xbox playstation ps4 ps3 ps5 casual translate" },
15  { label: "Website Localization", value: "website-localization.html", keywords: "html wordpress joomla drupal blog translate" },
16  { label: "App Store Description", value: "app-store-app-description-writing.html", keywords: "english apple google play appstore writing copywriting example" },
17  { label: "Press Releases", value: "app-press-release-writing.html", keywords: "english news pr prmac write writing copywriting example" },
18  { label: "Transcreation", value: "transcreation.html", keywords: "english language creative ads advertising SEO writing copywriting transcreate" },
19  { label: "Pseudolocalization", value: "pseudolocalization.html", keywords: "testing test formats xliff strings pot properties xml pseudo qa quality assurance" },
20  { label: "iOS Localization Tutorial", value: "iphone_app_localization.html", keywords: "do iphone step xcode xliff export import how help example guide" },
21  { label: "SwiftUI Localization Tutorial", value: "swiftui_localization_tutorial.html", keywords: "ios step xcode xliff export import how help example guide" },
22  { label: "Android Localization Services", value: "android_localization_services.html", keywords: "google studio xml values pixel samsung galaxy" },
23  {
24    label: "Android Localization Tutorial",
25    value: "android_app_localization_translation.html",
26    keywords: "do android google step studio strings.xml export import xml how help example guide",
27  },
28  {
29    label: "Adding Localized App Descriptions",
30    value: "add-localized-app-store-description-tutorial.html",
31    keywords: "itunes app store connect keyword languages how help example guide",
32  },
33  { label: "List of iOS & Android Language Codes", value: "iOS-Language-Codes-ISO-639.html", keywords: "lproj xcode official supported apple google languages how help guide" },
34  {
35    label: "iOS Multilingual Term Glossary",
36    value: "apple-ios-localization-term-glossary.html",
37    keywords:
38      "official supported dictionary translation translate keyword term base languages russian spanish chinese dutch korean french italian german korean japanese simplified traditional",
39  },
40  { label: "Localized Screenshots QA", value: "localized-screenshots-qa-review.html", keywords: "quality assurance how help test testing review revision in-app device guide" },
41  { label: "Localization Managers (LPM)", value: "localization-manager-vendors.html", keywords: "project lsp language service provider vendor why compare best practices" },
42  { label: "Localization Style Guides", value: "localization-style-guide-tips-best-practices.html", keywords: "project lpm lsp language service provider best practices" },
43  { label: "Localizing Your Help Center", value: "localizing-zendesk-wix-help-center.html", keywords: "knowledge base files export import translate" },
44  { label: "Crowdsourcing Management", value: "crowdsource_translation_management_localization.html", keywords: "crowdin lsp vendor help volunteers users" },
45  { label: "Crowdin + Babble-on", value: "crowdin.html", keywords: "crowdsourcing crowdsource" },
46  { label: "Pricing", value: "pricing.html", keywords: "cost money fee monthly setup hosting word roi estimat smartling onesky much" },
47  { label: "Plural translation in iOS", value: "ios_plurals_localizable_stringsdict.html", keywords: "stringsdict plist pluralization tutorial guide" },
48  { label: "Accidental Tech Podcast", value: "atp.html", keywords: "atp accidental tech podcast ad advertisement discount coupon" },
49
50]
51
52const DEFAULTS = {
53  threshold: 2,
54  maximumItems: 5,
55  highlightTyped: true,
56  highlightClass: "text-primary",
57}
58
59class Autocomplete {
60  constructor(field, options) {
61    this.field = field
62    this.options = Object.assign({}, DEFAULTS, options)
63    this.dropdown = null
64
65    field.parentNode.classList.add("dropdown")
66    field.setAttribute("data-toggle", "dropdown")
67    //field.classList.add('dropdown-toggle');
68
69    const dropdown = ce(`<div class="dropdown-menu" ></div>`)
70    if (this.options.dropdownClass) dropdown.classList.add(this.options.dropdownClass)
71
72    insertAfter(dropdown, field)
73
74    this.dropdown = new bootstrap.Dropdown(field, this.options.dropdownOptions)
75
76    field.addEventListener("click", (e) => {
77      if (this.createItems() === 0) {
78        e.stopPropagation()
79        this.dropdown.hide()
80      }
81    })
82
83    field.addEventListener("input", () => {
84      if (this.options.onInput) this.options.onInput(this.field.value)
85      this.renderIfNeeded()
86    })
87
88    field.addEventListener("keydown", (e) => {
89      if (e.keyCode === 27) {
90        this.dropdown.hide()
91        return
92      }
93    })
94
95    field.addEventListener("blur", (e) => {
96      this.dropdown.hide()
97    })
98  }
99
100  setData(data) {
101    this.options.data = data
102  }
103
104  renderIfNeeded() {
105    if (this.createItems() > 0) this.dropdown.show()
106    else this.field.click()
107  }
108
109  createItem(lookup, item) {
110    let label
111    const idx = item.label.toLowerCase().indexOf(lookup.toLowerCase())
112    if (this.options.highlightTyped && idx >= 0) {
113      const className = Array.isArray(this.options.highlightClass)
114        ? this.options.highlightClass.join(" ")
115        : typeof this.options.highlightClass == "string"
116        ? this.options.highlightClass
117        : ""
118      label =
119        item.label.substring(0, idx) +
120        `<span class="${className}">${item.label.substring(idx, idx + lookup.length)}</span>` +
121        item.label.substring(idx + lookup.length, item.label.length)
122    } else label = item.label
123    return ce(
124      `<button type="button" class="dropdown-item fw-bold" data-value="${item.value}">${label}<small class="text-muted ms-2" data-value="${item.value}"> – ${item.value}</small></button>`
125    )
126  }
127
128  createItems() {
129    const lookup = this.field.value
130    if (lookup.length < this.options.threshold) {
131      this.dropdown.hide()
132      return 0
133    }
134
135    const items = this.field.nextSibling
136    items.innerHTML = ""
137
138    let count = 0
139    for (let i = 0; i < this.options.data.length; i++) {
140      const { label, value, keywords } = this.options.data[i]
141      const item = { label, value, keywords }
142      var bloodhound = item.label + " " + item.keywords + " " + item.value.replace(/(_|-)/g, " ")
143      if (bloodhound.toLowerCase().indexOf(lookup.toLowerCase()) >= 0) {
144        // if (item.label.toLowerCase().indexOf(lookup.toLowerCase()) >= 0) {
145        items.appendChild(this.createItem(lookup, item))
146        if (this.options.maximumItems > 0 && ++count >= this.options.maximumItems) break
147      }
148    }
149
150    this.field.nextSibling.querySelectorAll(".dropdown-item").forEach((item) => {
151      item.addEventListener("click", (e) => {
152        let dataValue = e.target.getAttribute("data-value")
153        let dataText = e.target.innerText.substring(0, e.target.innerText.indexOf("–")).trim()
154        this.field.value = dataText
155        if (this.options.onSelectItem)
156          this.options.onSelectItem({
157            value: e.target.dataset.value,
158            label: dataText,
159          })
160        this.dropdown.hide()
161      })
162    })
163
164    return items.childNodes.length
165  }
166}
167
168/**
169 * @param html
170 * @returns {Node}
171 */
172function ce(html) {
173  let div = document.createElement("div")
174  div.innerHTML = html
175  return div.firstChild
176}
177
178/**
179 * @param elem
180 * @param refElem
181 * @returns {*}
182 */
183function insertAfter(elem, refElem) {
184  return refElem.parentNode.insertBefore(elem, refElem.nextSibling)
185}
186
187const ac = new Autocomplete(field, {
188  data: datasrc,
189  maximumItems: 5,
190  threshold: 0,
191  highlightTyped: true,
192  highlightClass: "text-primary h6",
193  onSelectItem: ({ label, value }) => {
194    window.location.href = "https://www.ibabbleon.com/" + value
195  },
196})

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.