chrome-devtools-frontend
Version:
Chrome DevTools UI
49 lines (41 loc) • 1.49 kB
text/typescript
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
export class SecurityOrigin {
#urlOrigin?: string;
#opaqueUuid?: string;
private constructor(urlOrigin?: string, opaqueUuid?: string) {
this.#urlOrigin = urlOrigin;
this.#opaqueUuid = opaqueUuid;
}
static create(urlOrigin: string): SecurityOrigin {
return new SecurityOrigin(urlOrigin, undefined);
}
static createUniqueOpaque(): SecurityOrigin {
return new SecurityOrigin(undefined, crypto.randomUUID());
}
isSameOriginWith(other: SecurityOrigin): boolean {
if (this.#opaqueUuid || other.#opaqueUuid) {
return this.#opaqueUuid === other.#opaqueUuid;
}
if (this.isOpaque() || other.isOpaque()) {
return false;
}
return this.#urlOrigin === other.#urlOrigin && this.#urlOrigin !== undefined;
}
isOpaque(): boolean {
if (this.#opaqueUuid !== undefined) {
return true;
}
if (this.#urlOrigin) {
const lower = this.#urlOrigin.toLowerCase();
return lower === '' || lower === 'null' || lower === 'data:' || lower.startsWith('about') ||
lower.startsWith('blob:about') || lower.startsWith('blob:data') || lower.startsWith('blob:null') ||
lower.startsWith('detached') || lower.startsWith('undefined');
}
return false;
}
siteId(): string {
return this.#opaqueUuid ?? (this.#urlOrigin ?? 'unknown-origin');
}
}