Skip to content

Commit

Permalink
Merge pull request #90 from seanpdoyle/use-browser-url
Browse files Browse the repository at this point in the history
Replace `Location` class with browser-provided URL
  • Loading branch information
sstephenson authored Jan 21, 2021
2 parents 178c817 + 9a81d03 commit f9d1651
Show file tree
Hide file tree
Showing 17 changed files with 154 additions and 205 deletions.
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
}

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

0 comments on commit f9d1651

Please sign in to comment.