@quick-game/cli
Version:
Command line interface for rapid qg development
247 lines • 10.4 kB
JavaScript
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Common from '../../core/common/common.js';
import * as Host from '../../core/host/host.js';
import * as Diff from '../../third_party/diff/diff.js';
import * as FormatterModule from '../formatter/formatter.js';
import * as Persistence from '../persistence/persistence.js';
import * as Workspace from '../workspace/workspace.js';
export class WorkspaceDiffImpl extends Common.ObjectWrapper.ObjectWrapper {
uiSourceCodeDiffs;
loadingUISourceCodes;
modifiedUISourceCodesInternal;
constructor(workspace) {
super();
this.uiSourceCodeDiffs = new WeakMap();
this.loadingUISourceCodes = new Map();
this.modifiedUISourceCodesInternal = new Set();
workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyChanged, this.uiSourceCodeChanged, this);
workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyCommitted, this.uiSourceCodeChanged, this);
workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this.uiSourceCodeAdded, this);
workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this.uiSourceCodeRemoved, this);
workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this.projectRemoved, this);
workspace.uiSourceCodes().forEach(this.updateModifiedState.bind(this));
}
requestDiff(uiSourceCode, diffRequestOptions) {
return this.uiSourceCodeDiff(uiSourceCode).requestDiff(diffRequestOptions);
}
subscribeToDiffChange(uiSourceCode, callback, thisObj) {
this.uiSourceCodeDiff(uiSourceCode).addEventListener(UISourceCodeDiffEvents.DiffChanged, callback, thisObj);
}
unsubscribeFromDiffChange(uiSourceCode, callback, thisObj) {
this.uiSourceCodeDiff(uiSourceCode).removeEventListener(UISourceCodeDiffEvents.DiffChanged, callback, thisObj);
}
modifiedUISourceCodes() {
return Array.from(this.modifiedUISourceCodesInternal);
}
isUISourceCodeModified(uiSourceCode) {
return this.modifiedUISourceCodesInternal.has(uiSourceCode) || this.loadingUISourceCodes.has(uiSourceCode);
}
uiSourceCodeDiff(uiSourceCode) {
let diff = this.uiSourceCodeDiffs.get(uiSourceCode);
if (!diff) {
diff = new UISourceCodeDiff(uiSourceCode);
this.uiSourceCodeDiffs.set(uiSourceCode, diff);
}
return diff;
}
uiSourceCodeChanged(event) {
const uiSourceCode = event.data.uiSourceCode;
void this.updateModifiedState(uiSourceCode);
}
uiSourceCodeAdded(event) {
const uiSourceCode = event.data;
void this.updateModifiedState(uiSourceCode);
}
uiSourceCodeRemoved(event) {
const uiSourceCode = event.data;
this.removeUISourceCode(uiSourceCode);
}
projectRemoved(event) {
const project = event.data;
for (const uiSourceCode of project.uiSourceCodes()) {
this.removeUISourceCode(uiSourceCode);
}
}
removeUISourceCode(uiSourceCode) {
this.loadingUISourceCodes.delete(uiSourceCode);
const uiSourceCodeDiff = this.uiSourceCodeDiffs.get(uiSourceCode);
if (uiSourceCodeDiff) {
uiSourceCodeDiff.dispose = true;
}
this.markAsUnmodified(uiSourceCode);
}
markAsUnmodified(uiSourceCode) {
this.uiSourceCodeProcessedForTest();
if (this.modifiedUISourceCodesInternal.delete(uiSourceCode)) {
this.dispatchEventToListeners("ModifiedStatusChanged" /* Events.ModifiedStatusChanged */, { uiSourceCode, isModified: false });
}
}
markAsModified(uiSourceCode) {
this.uiSourceCodeProcessedForTest();
if (this.modifiedUISourceCodesInternal.has(uiSourceCode)) {
return;
}
this.modifiedUISourceCodesInternal.add(uiSourceCode);
this.dispatchEventToListeners("ModifiedStatusChanged" /* Events.ModifiedStatusChanged */, { uiSourceCode, isModified: true });
}
uiSourceCodeProcessedForTest() {
}
async updateModifiedState(uiSourceCode) {
this.loadingUISourceCodes.delete(uiSourceCode);
if (uiSourceCode.project().type() !== Workspace.Workspace.projectTypes.Network) {
this.markAsUnmodified(uiSourceCode);
return;
}
if (uiSourceCode.isDirty()) {
this.markAsModified(uiSourceCode);
return;
}
if (!uiSourceCode.hasCommits()) {
this.markAsUnmodified(uiSourceCode);
return;
}
const contentsPromise = Promise.all([
this.requestOriginalContentForUISourceCode(uiSourceCode),
uiSourceCode.requestContent().then(deferredContent => deferredContent.content),
]);
this.loadingUISourceCodes.set(uiSourceCode, contentsPromise);
const contents = await contentsPromise;
if (this.loadingUISourceCodes.get(uiSourceCode) !== contentsPromise) {
return;
}
this.loadingUISourceCodes.delete(uiSourceCode);
if (contents[0] !== null && contents[1] !== null && contents[0] !== contents[1]) {
this.markAsModified(uiSourceCode);
}
else {
this.markAsUnmodified(uiSourceCode);
}
}
requestOriginalContentForUISourceCode(uiSourceCode) {
return this.uiSourceCodeDiff(uiSourceCode).originalContent();
}
revertToOriginal(uiSourceCode) {
function callback(content) {
if (typeof content !== 'string') {
return;
}
uiSourceCode.addRevision(content);
}
Host.userMetrics.actionTaken(Host.UserMetrics.Action.RevisionApplied);
return this.requestOriginalContentForUISourceCode(uiSourceCode).then(callback);
}
}
export class UISourceCodeDiff extends Common.ObjectWrapper.ObjectWrapper {
uiSourceCode;
requestDiffPromise;
pendingChanges;
dispose;
constructor(uiSourceCode) {
super();
this.uiSourceCode = uiSourceCode;
uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this.uiSourceCodeChanged, this);
uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted, this.uiSourceCodeChanged, this);
this.requestDiffPromise = null;
this.pendingChanges = null;
this.dispose = false;
}
uiSourceCodeChanged() {
if (this.pendingChanges) {
clearTimeout(this.pendingChanges);
this.pendingChanges = null;
}
this.requestDiffPromise = null;
const content = this.uiSourceCode.content();
const delay = (!content || content.length < 65536) ? 0 : UpdateTimeout;
this.pendingChanges = window.setTimeout(emitDiffChanged.bind(this), delay);
function emitDiffChanged() {
if (this.dispose) {
return;
}
this.dispatchEventToListeners(UISourceCodeDiffEvents.DiffChanged);
this.pendingChanges = null;
}
}
requestDiff(diffRequestOptions) {
if (!this.requestDiffPromise) {
this.requestDiffPromise = this.innerRequestDiff(diffRequestOptions);
}
return this.requestDiffPromise;
}
async originalContent() {
const originalNetworkContent = Persistence.NetworkPersistenceManager.NetworkPersistenceManager.instance().originalContentForUISourceCode(this.uiSourceCode);
if (originalNetworkContent) {
return originalNetworkContent;
}
const content = await this.uiSourceCode.project().requestFileContent(this.uiSourceCode);
return content.content || ('error' in content && content.error) || '';
}
async innerRequestDiff({ shouldFormatDiff }) {
if (this.dispose) {
return null;
}
let baseline = await this.originalContent();
if (baseline === null) {
return null;
}
if (baseline.length > 1024 * 1024) {
return null;
}
// ------------ ASYNC ------------
if (this.dispose) {
return null;
}
let current = this.uiSourceCode.workingCopy();
if (!current && !this.uiSourceCode.contentLoaded()) {
current = (await this.uiSourceCode.requestContent()).content;
}
if (current.length > 1024 * 1024) {
return null;
}
if (this.dispose) {
return null;
}
if (current === null || baseline === null) {
return null;
}
let formattedCurrentMapping;
if (shouldFormatDiff) {
baseline = (await FormatterModule.ScriptFormatter.format(this.uiSourceCode.contentType(), this.uiSourceCode.mimeType(), baseline))
.formattedContent;
const formatCurrentResult = await FormatterModule.ScriptFormatter.format(this.uiSourceCode.contentType(), this.uiSourceCode.mimeType(), current);
current = formatCurrentResult.formattedContent;
formattedCurrentMapping = formatCurrentResult.formattedMapping;
}
const reNewline = /\r\n?|\n/;
const diff = Diff.Diff.DiffWrapper.lineDiff(baseline.split(reNewline), current.split(reNewline));
return {
diff,
formattedCurrentMapping,
};
}
}
// TODO(crbug.com/1167717): Make this a const enum again
// eslint-disable-next-line rulesdir/const_enum
export var UISourceCodeDiffEvents;
(function (UISourceCodeDiffEvents) {
UISourceCodeDiffEvents["DiffChanged"] = "DiffChanged";
})(UISourceCodeDiffEvents || (UISourceCodeDiffEvents = {}));
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
// eslint-disable-next-line @typescript-eslint/naming-convention
let _instance = null;
export function workspaceDiff() {
if (!_instance) {
_instance = new WorkspaceDiffImpl(Workspace.Workspace.WorkspaceImpl.instance());
}
return _instance;
}
export class DiffUILocation {
uiSourceCode;
constructor(uiSourceCode) {
this.uiSourceCode = uiSourceCode;
}
}
export const UpdateTimeout = 200;
//# sourceMappingURL=WorkspaceDiff.js.map