Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 115 additions & 58 deletions playground/src/controllers/playground_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { analyzeRuby } from "../analyze-ruby"
window.Herb = Herb
window.analyze = analyze

const URL_UPDATE_THROTTLE = 100

const exampleFile = dedent`
<!-- Example HTML+ERB File -->

Expand Down Expand Up @@ -143,6 +145,11 @@ export default class extends Controller {
"diffParseError",
]

pendingHash = null
pendingSearch = null
urlUpdateTimeout = null
lastURLUpdateAt = 0

get isRubyMode() {
return this.modeValue === "ruby"
}
Expand Down Expand Up @@ -286,6 +293,13 @@ export default class extends Controller {

disconnect() {
window.removeEventListener("popstate", this.handlePopState)

if (this.urlUpdateTimeout !== null) {
clearTimeout(this.urlUpdateTimeout)
this.urlUpdateTimeout = null
this.flushURLUpdate()
}

this.removeTooltip()
this.removeAutofixTooltip()
this.removeAutofixUnsafeTooltip()
Expand All @@ -309,7 +323,7 @@ export default class extends Controller {
}

updateURL() {
window.parent.location.hash = this.compressedValue
this.queueURLUpdate({ hash: this.compressedValue })

if (!this.isRubyMode) {
const options = this.getParserOptions()
Expand All @@ -323,6 +337,61 @@ export default class extends Controller {
}
}

updateSearchParams(update) {
const params = new URLSearchParams(
this.pendingSearch !== null ? this.pendingSearch : window.parent.location.search,
)

update(params)

this.queueURLUpdate({ search: params.toString() })
}

queueURLUpdate({ hash, search }) {
if (hash !== undefined) this.pendingHash = hash
if (search !== undefined) this.pendingSearch = search

if (this.urlUpdateTimeout !== null) return
if (!this.hasPendingURLUpdate) return

const elapsed = Date.now() - this.lastURLUpdateAt

this.urlUpdateTimeout = setTimeout(() => {
this.urlUpdateTimeout = null
this.flushURLUpdate()
}, Math.max(0, URL_UPDATE_THROTTLE - elapsed))
}

get hasPendingURLUpdate() {
const location = window.parent.location

if (this.pendingHash !== null && this.pendingHash !== location.hash.slice(1)) return true
if (this.pendingSearch !== null && this.pendingSearch !== new URLSearchParams(location.search).toString()) return true

return false
}

flushURLUpdate() {
const location = window.parent.location
const hash = this.pendingHash
const search = this.pendingSearch

this.pendingHash = null
this.pendingSearch = null
this.lastURLUpdateAt = Date.now()

if (hash !== null && hash !== location.hash.slice(1)) {
location.hash = hash
}

if (search === null || search === new URLSearchParams(location.search).toString()) return

const url = new URL(location)
url.search = search

window.parent.history.replaceState({}, '', url)
}

async insert(event) {
if (
this.inputTarget.value !== "" &&
Expand Down Expand Up @@ -606,19 +675,17 @@ export default class extends Controller {
}

updateTabInURL(tabName) {
const url = new URL(window.parent.location)

if (tabName && tabName !== 'parse') {
url.searchParams.set('tab', tabName)
} else {
url.searchParams.delete('tab')
}

if (tabName !== 'diagnostics') {
url.searchParams.delete('diagnosticsFilter')
}
this.updateSearchParams((params) => {
if (tabName && tabName !== 'parse') {
params.set('tab', tabName)
} else {
params.delete('tab')
}

window.parent.history.replaceState({}, '', url)
if (tabName !== 'diagnostics') {
params.delete('diagnosticsFilter')
}
})
}

getClosestButton(element) {
Expand Down Expand Up @@ -1973,8 +2040,6 @@ export default class extends Controller {
}

setOptionsInURL(options) {
const url = new URL(window.parent.location)

const defaults = {
track_whitespace: false,
analyze: true,
Expand Down Expand Up @@ -2002,18 +2067,16 @@ export default class extends Controller {
}
})

if (Object.keys(nonDefaultOptions).length > 0) {
url.searchParams.set('options', JSON.stringify(nonDefaultOptions))
} else {
url.searchParams.delete('options')
}

window.parent.history.replaceState({}, '', url)
this.updateSearchParams((params) => {
if (Object.keys(nonDefaultOptions).length > 0) {
params.set('options', JSON.stringify(nonDefaultOptions))
} else {
params.delete('options')
}
})
}

setPrinterOptionsInURL(printerOptions) {
const url = new URL(window.parent.location)

const defaults = {
ignoreErrors: false,
}
Expand All @@ -2029,13 +2092,13 @@ export default class extends Controller {
}
})

if (Object.keys(nonDefaultPrinterOptions).length > 0) {
url.searchParams.set('printerOptions', JSON.stringify(nonDefaultPrinterOptions))
} else {
url.searchParams.delete('printerOptions')
}

window.parent.history.replaceState({}, '', url)
this.updateSearchParams((params) => {
if (Object.keys(nonDefaultPrinterOptions).length > 0) {
params.set('printerOptions', JSON.stringify(nonDefaultPrinterOptions))
} else {
params.delete('printerOptions')
}
})
}

getPrinterOptionsFromURL() {
Expand All @@ -2054,8 +2117,6 @@ export default class extends Controller {
}

setFormatterOptionsInURL(formatterOptions) {
const url = new URL(window.parent.location)

const nonDefaultFormatterOptions = {}

Object.keys(formatterOptions).forEach(key => {
Expand All @@ -2064,13 +2125,13 @@ export default class extends Controller {
}
})

if (Object.keys(nonDefaultFormatterOptions).length > 0) {
url.searchParams.set('formatterOptions', JSON.stringify(nonDefaultFormatterOptions))
} else {
url.searchParams.delete('formatterOptions')
}

window.parent.history.replaceState({}, '', url)
this.updateSearchParams((params) => {
if (Object.keys(nonDefaultFormatterOptions).length > 0) {
params.set('formatterOptions', JSON.stringify(nonDefaultFormatterOptions))
} else {
params.delete('formatterOptions')
}
})
}

getFormatterOptionsFromURL() {
Expand All @@ -2089,8 +2150,6 @@ export default class extends Controller {
}

setAutofixOptionsInURL(autofixOptions) {
const url = new URL(window.parent.location)

const defaults = {
includeUnsafe: false,
}
Expand All @@ -2106,13 +2165,13 @@ export default class extends Controller {
}
})

if (Object.keys(nonDefaultAutofixOptions).length > 0) {
url.searchParams.set('autofixOptions', JSON.stringify(nonDefaultAutofixOptions))
} else {
url.searchParams.delete('autofixOptions')
}

window.parent.history.replaceState({}, '', url)
this.updateSearchParams((params) => {
if (Object.keys(nonDefaultAutofixOptions).length > 0) {
params.set('autofixOptions', JSON.stringify(nonDefaultAutofixOptions))
} else {
params.delete('autofixOptions')
}
})
}

getAutofixOptionsFromURL() {
Expand Down Expand Up @@ -2142,15 +2201,13 @@ export default class extends Controller {
}

updateDiagnosticsFilterInURL(filter) {
const url = new URL(window.parent.location)

if (filter && filter !== 'all') {
url.searchParams.set('diagnosticsFilter', filter)
} else {
url.searchParams.delete('diagnosticsFilter')
}

window.parent.history.replaceState({}, '', url)
this.updateSearchParams((params) => {
if (filter && filter !== 'all') {
params.set('diagnosticsFilter', filter)
} else {
params.delete('diagnosticsFilter')
}
})
}

updateDiagnosticsViewer(diagnostics) {
Expand Down
Loading