Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Location class with browser-provided URL #90

Merged
merged 4 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
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
6 changes: 3 additions & 3 deletions src/core/drive/form_submission.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FetchRequest, FetchMethod, fetchMethodFromString, FetchRequestHeaders } from "../../http/fetch_request"
import { FetchResponse } from "../../http/fetch_response"
import { Location } from "../location"
import { expandURL } from "../url"
import { dispatch } from "../../util"

export interface FormSubmissionDelegate {
Expand Down Expand Up @@ -52,8 +52,8 @@ export class FormSubmission {
return this.submitter?.getAttribute("formaction") || this.formElement.action
}

get location() {
return Location.wrap(this.action)
get location(): URL {
return expandURL(this.action)
}

// The submission process
Expand Down
20 changes: 9 additions & 11 deletions src/core/drive/history.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Location } from "../location"
import { Position } from "../types"
import { nextMicrotask, uuid } from "../../util"

export interface HistoryDelegate {
historyPoppedToLocationWithRestorationIdentifier(location: Location, restorationIdentifier: string): void
historyPoppedToLocationWithRestorationIdentifier(location: URL, restorationIdentifier: string): void
seanpdoyle marked this conversation as resolved.
Show resolved Hide resolved
}

type HistoryMethod = (this: typeof history, state: any, title: string, url?: string | null | undefined) => void
Expand All @@ -14,7 +13,7 @@ export type RestorationDataMap = { [restorationIdentifier: string]: RestorationD

export class History {
readonly delegate: HistoryDelegate
location!: Location
location!: URL
restorationIdentifier = uuid()
restorationData: RestorationDataMap = {}
started = false
Expand All @@ -30,7 +29,7 @@ export class History {
addEventListener("popstate", this.onPopState, false)
addEventListener("load", this.onPageLoad, false)
this.started = true
this.replace(Location.currentLocation)
this.replace(new URL(window.location.href))
}
}

Expand All @@ -42,17 +41,17 @@ export class History {
}
}

push(location: Location, restorationIdentifier?: string) {
push(location: URL, restorationIdentifier?: string) {
this.update(history.pushState, location, restorationIdentifier)
}

replace(location: Location, restorationIdentifier?: string) {
replace(location: URL, restorationIdentifier?: string) {
this.update(history.replaceState, location, restorationIdentifier)
}

update(method: HistoryMethod, location: Location, restorationIdentifier = uuid()) {
update(method: HistoryMethod, location: URL, restorationIdentifier = uuid()) {
const state = { turbo: { restorationIdentifier } }
method.call(history, state, "", location.absoluteURL)
method.call(history, state, "", location.href)
this.location = location
this.restorationIdentifier = restorationIdentifier
}
Expand Down Expand Up @@ -91,11 +90,10 @@ export class History {
if (this.shouldHandlePopState()) {
const { turbo } = event.state || {}
if (turbo) {
const location = Location.currentLocation
this.location = location
this.location = new URL(window.location.href)
const { restorationIdentifier } = turbo
this.restorationIdentifier = restorationIdentifier
this.delegate.historyPoppedToLocationWithRestorationIdentifier(location, restorationIdentifier)
this.delegate.historyPoppedToLocationWithRestorationIdentifier(this.location, restorationIdentifier)
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/core/drive/navigator.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { FetchMethod } from "../../http/fetch_request"
import { FetchResponse } from "../../http/fetch_response"
import { FormSubmission } from "./form_submission"
import { Locatable, Location } from "../location"
import { expandURL, Locatable } from "../url"
import { Visit, VisitDelegate, VisitOptions } from "./visit"
import { Snapshot } from "./snapshot"

export type NavigatorDelegate = VisitDelegate & {
allowsVisitingLocation(location: Location): boolean
visitProposedToLocation(location: Location, options: Partial<VisitOptions>): void
allowsVisitingLocation(location: URL): boolean
visitProposedToLocation(location: URL, options: Partial<VisitOptions>): void
}

export class Navigator {
Expand All @@ -19,15 +19,15 @@ export class Navigator {
this.delegate = delegate
}

proposeVisit(location: Location, options: Partial<VisitOptions> = {}) {
proposeVisit(location: URL, options: Partial<VisitOptions> = {}) {
if (this.delegate.allowsVisitingLocation(location)) {
this.delegate.visitProposedToLocation(location, options)
}
}

startVisit(location: Locatable, restorationIdentifier: string, options: Partial<VisitOptions> = {}) {
startVisit(locatable: Locatable, restorationIdentifier: string, options: Partial<VisitOptions> = {}) {
this.stop()
this.currentVisit = new Visit(this, Location.wrap(location), restorationIdentifier, {
this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, {
referrer: this.location,
...options
})
Expand Down
6 changes: 3 additions & 3 deletions src/core/drive/snapshot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HeadDetails } from "./head_details"
import { Location } from "../location"
import { expandURL } from "../url"

export class Snapshot {
static wrap(value: Snapshot | string | HTMLHtmlElement) {
Expand Down Expand Up @@ -37,9 +37,9 @@ export class Snapshot {
return new Snapshot(this.headDetails, bodyElement)
}

getRootLocation() {
getRootLocation(): URL {
const root = this.getSetting("root", "/")
return new Location(root)
return expandURL(root)
}

getCacheControlValue() {
Expand Down
22 changes: 11 additions & 11 deletions src/core/drive/snapshot_cache.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Location } from "../location"
import { toCacheKey } from "../url"
import { Snapshot } from "./snapshot"

export class SnapshotCache {
Expand All @@ -10,19 +10,19 @@ export class SnapshotCache {
this.size = size
}

has(location: Location) {
return location.toCacheKey() in this.snapshots
has(location: URL) {
return toCacheKey(location) in this.snapshots
}

get(location: Location): Snapshot | undefined {
get(location: URL): Snapshot | undefined {
if (this.has(location)) {
const snapshot = this.read(location)
this.touch(location)
return snapshot
}
}

put(location: Location, snapshot: Snapshot) {
put(location: URL, snapshot: Snapshot) {
this.write(location, snapshot)
this.touch(location)
return snapshot
Expand All @@ -34,16 +34,16 @@ export class SnapshotCache {

// Private

read(location: Location) {
return this.snapshots[location.toCacheKey()]
read(location: URL) {
return this.snapshots[toCacheKey(location)]
}

write(location: Location, snapshot: Snapshot) {
this.snapshots[location.toCacheKey()] = snapshot
write(location: URL, snapshot: Snapshot) {
this.snapshots[toCacheKey(location)] = snapshot
}

touch(location: Location) {
const key = location.toCacheKey()
touch(location: URL) {
const key = toCacheKey(location)
const index = this.keys.indexOf(key)
if (index > -1) this.keys.splice(index, 1)
this.keys.unshift(key)
Expand Down
9 changes: 4 additions & 5 deletions src/core/drive/view.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ErrorRenderer } from "./error_renderer"
import { Location } from "../location"
import { Snapshot } from "./snapshot"
import { SnapshotCache } from "./snapshot_cache"
import { RenderCallback, RenderDelegate, SnapshotRenderer } from "./snapshot_renderer"
Expand All @@ -16,13 +15,13 @@ export class View {
readonly delegate: ViewDelegate
readonly htmlElement = document.documentElement as HTMLHtmlElement
readonly snapshotCache = new SnapshotCache(10)
lastRenderedLocation?: Location
lastRenderedLocation?: URL

constructor(delegate: ViewDelegate) {
this.delegate = delegate
}

getRootLocation(): Location {
getRootLocation(): URL {
return this.getSnapshot().getRootLocation()
}

Expand All @@ -46,13 +45,13 @@ export class View {
if (this.shouldCacheSnapshot()) {
this.delegate.viewWillCacheSnapshot()
const snapshot = this.getSnapshot()
const location = this.lastRenderedLocation || Location.currentLocation
const location = this.lastRenderedLocation || new URL(window.location.href)
await nextMicrotask()
this.snapshotCache.put(location, snapshot.clone())
}
}

getCachedSnapshotForLocation(location: Location) {
getCachedSnapshotForLocation(location: URL) {
return this.snapshotCache.get(location)
}

Expand Down
20 changes: 10 additions & 10 deletions src/core/drive/visit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Adapter } from "../native/adapter"
import { FetchMethod, FetchRequest, FetchRequestDelegate } from "../../http/fetch_request"
import { FetchResponse } from "../../http/fetch_response"
import { History } from "./history"
import { Location } from "../location"
import { getAnchor } from "../url"
import { RenderCallback } from "./renderer"
import { Snapshot } from "./snapshot"
import { Action } from "../types"
Expand Down Expand Up @@ -38,7 +38,7 @@ export enum VisitState {
export type VisitOptions = {
action: Action,
historyChanged: boolean,
referrer?: Location,
referrer?: URL,
snapshotHTML?: string,
response?: VisitResponse
}
Expand All @@ -64,22 +64,22 @@ export class Visit implements FetchRequestDelegate {
readonly identifier = uuid()
readonly restorationIdentifier: string
readonly action: Action
readonly referrer?: Location
readonly referrer?: URL
readonly timingMetrics: TimingMetrics = {}

followedRedirect = false
frame?: number
historyChanged = false
location: Location
redirectedToLocation?: Location
location: URL
redirectedToLocation?: URL
request?: FetchRequest
response?: VisitResponse
scrolled = false
snapshotHTML?: string
snapshotCached = false
state = VisitState.initialized

constructor(delegate: VisitDelegate, location: Location, restorationIdentifier: string | undefined, options: Partial<VisitOptions> = {}) {
constructor(delegate: VisitDelegate, location: URL, restorationIdentifier: string | undefined, options: Partial<VisitOptions> = {}) {
this.delegate = delegate
this.location = location
this.restorationIdentifier = restorationIdentifier || uuid()
Expand Down Expand Up @@ -145,7 +145,7 @@ export class Visit implements FetchRequestDelegate {

changeHistory() {
if (!this.historyChanged) {
const actionForHistory = this.location.isEqualTo(this.referrer) ? "replace" : this.action
const actionForHistory = this.location.href === this.referrer?.href ? "replace" : this.action
const method = this.getHistoryMethodForAction(actionForHistory)
this.history.update(method, this.location, this.restorationIdentifier)
this.historyChanged = true
Expand Down Expand Up @@ -212,7 +212,7 @@ export class Visit implements FetchRequestDelegate {
getCachedSnapshot() {
const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot()

if (snapshot && (!this.location.anchor || snapshot.hasAnchor(this.location.anchor))) {
if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) {
if (this.action == "restore" || snapshot.isPreviewable()) {
return snapshot
}
Expand Down Expand Up @@ -311,8 +311,8 @@ export class Visit implements FetchRequestDelegate {
}

scrollToAnchor() {
if (this.location.anchor != null) {
this.view.scrollToAnchor(this.location.anchor)
if (getAnchor(this.location) != null) {
this.view.scrollToAnchor(getAnchor(this.location))
return true
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/core/frames/frame_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { FetchResponse } from "../../http/fetch_response"
import { AppearanceObserver, AppearanceObserverDelegate } from "../../observers/appearance_observer"
import { nextAnimationFrame } from "../../util"
import { FormSubmission, FormSubmissionDelegate } from "../drive/form_submission"
import { Locatable, Location } from "../location"
import { FormInterceptor, FormInterceptorDelegate } from "./form_interceptor"
import { LinkInterceptor, LinkInterceptorDelegate } from "./link_interceptor"
import { expandURL, Locatable } from "../url"

export class FrameController implements AppearanceObserverDelegate, FetchRequestDelegate, FormInterceptorDelegate, FormSubmissionDelegate, FrameElementDelegate, LinkInterceptorDelegate {
readonly element: FrameElement
Expand Down Expand Up @@ -107,7 +107,7 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest

this.formSubmission = new FormSubmission(this, element, submitter)
if (this.formSubmission.fetchRequest.isIdempotent) {
this.navigateFrame(element, this.formSubmission.fetchRequest.url)
this.navigateFrame(element, this.formSubmission.fetchRequest.url.href)
} else {
this.formSubmission.start()
}
Expand Down Expand Up @@ -172,8 +172,7 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest
// Private

private async visit(url: Locatable) {
const location = Location.wrap(url)
const request = new FetchRequest(this, FetchMethod.get, location)
const request = new FetchRequest(this, FetchMethod.get, expandURL(url))

return new Promise<void>(resolve => {
this.resolveVisitPromise = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Adapter } from "./native/adapter"
import { Session } from "./session"
import { Locatable } from "./location"
import { Locatable } from "./url"
import { StreamMessage } from "./streams/stream_message"
import { StreamSource } from "./types"
import { VisitOptions } from "./drive/visit"
Expand Down
Loading