codex-overleaf-link 2.2.1 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -23
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/runtime-manifest.json +5 -71
- package/extension/src/background.js +67 -63
- package/extension/src/backgroundUpdateCoordinator.js +128 -66
- package/extension/src/content/applyResultFormatters.js +2 -3
- package/extension/src/content/composerPanel.js +0 -2
- package/extension/src/content/contentRuntime.js +757 -1558
- package/extension/src/content/contextTray.js +4 -6
- package/extension/src/content/diagnosticsController.js +1 -2
- package/extension/src/content/diffReviewPanel.js +14 -13
- package/extension/src/content/generated/content.bundle.js +41605 -0
- package/extension/src/content/generated/content.bundle.meta.json +103 -0
- package/extension/src/content/legacyGlobalRegistry.js +129 -0
- package/extension/src/content/markdownText.js +17 -17
- package/extension/src/content/mathText.js +155 -9
- package/extension/src/content/modelPicker.js +1 -1
- package/extension/src/content/modelPickerSupport.js +10 -5
- package/extension/src/content/moduleRegistryKernel.js +125 -0
- package/extension/src/content/nativeCompatibilityController.js +313 -0
- package/extension/src/content/otWarmMirror.js +8 -6
- package/extension/src/content/pageBridgeClient.js +224 -0
- package/extension/src/content/panelMaintenance.js +8 -3
- package/extension/src/content/postNavigationSettlementPersistence.js +100 -0
- package/extension/src/content/projectProviderSelection.js +4 -12
- package/extension/src/content/projectSessionCleanup.js +3 -3
- package/extension/src/content/providerSettingsCoordinator.js +59 -26
- package/extension/src/content/providerSettingsDialog.js +30 -18
- package/extension/src/content/recentProjects.js +15 -23
- package/extension/src/content/runGuidanceController.js +1 -1
- package/extension/src/content/runQueueScheduler.js +129 -29
- package/extension/src/content/runSettlementPersistence.js +51 -0
- package/extension/src/content/runTimelineView.js +17 -8
- package/extension/src/content/scopedPersistenceCoordinator.js +100 -0
- package/extension/src/content/scopedPersistenceDetachedCommit.js +47 -0
- package/extension/src/content/scopedPersistencePanelState.js +111 -0
- package/extension/src/content/sessionManager.js +15 -12
- package/extension/src/content/sessionPersistence.js +67 -8
- package/extension/src/content/updateNotice.js +10 -4
- package/extension/src/content/writebackOrchestrator.js +89 -68
- package/extension/src/contentScript.js +5 -1
- package/extension/src/page/trackedChangesLifecycle.js +16 -5
- package/extension/src/page/writebackRouter.js +6 -2
- package/extension/src/pageBridge.js +47 -98
- package/extension/src/shared/agentTranscript.js +18 -8
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/src/shared/governanceRules.js +1 -1
- package/extension/src/shared/i18n.js +2 -4
- package/extension/src/shared/managedUpdateProjection.js +337 -0
- package/extension/src/shared/nativeRequestIdentity.js +60 -0
- package/extension/src/shared/otText.js +0 -19
- package/extension/src/shared/pageRpcContract.js +136 -0
- package/extension/src/shared/runExecutionSnapshot.js +187 -0
- package/extension/src/shared/runExecutionSnapshotCodec.js +171 -0
- package/extension/src/shared/runInputQueue.js +81 -34
- package/extension/src/shared/scopedPersistenceBrowserAdapter.js +79 -0
- package/extension/src/shared/scopedPersistenceQueuePolicy.js +200 -0
- package/extension/src/shared/scopedPersistenceReceipt.js +60 -0
- package/extension/src/shared/scopedPersistenceTransaction.js +241 -0
- package/extension/src/shared/sessionState.js +110 -59
- package/extension/src/shared/settlementFacts.js +351 -0
- package/extension/src/shared/storageDb.js +25 -10
- package/extension/src/shared/storageMigration.js +275 -61
- package/extension/src/shared/storageSessionClaims.js +60 -0
- package/extension/src/shared/updateConsent.js +4 -0
- package/extension/src/shared/updateRevocationIntent.js +109 -0
- package/extension/src/shared/writebackEvidenceProjection.js +150 -0
- package/extension/src/shared/writebackOperationEvidence.js +153 -0
- package/extension/src/shared/writebackSettlement.js +727 -0
- package/extension/styles/panel.css +18 -8
- package/native-host/src/codexPromptAssembly.js +1 -1
- package/native-host/src/codexRuntimeIdentity.js +1 -1
- package/native-host/src/codexSessionRunner.js +7 -13
- package/native-host/src/index.js +3 -69
- package/native-host/src/managedInstall.js +50 -8
- package/native-host/src/nativeTransportEnvelope.js +148 -0
- package/native-host/src/taskRunnerRuntime.js +14 -84
- package/native-host/src/updateManager.js +36 -1
- package/package.json +13 -5
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"entry": "extension/entries/content-entry.mjs",
|
|
4
|
+
"output": "extension/src/content/generated/content.bundle.js",
|
|
5
|
+
"sourceDigest": "ddbc07ac8d34d864aa3648c53211c5858e0312a73df815a0392bc52ec5eac1cc",
|
|
6
|
+
"outputDigest": "42051c8624bdfca3094c8bef2430094e55b7e1ec49d475ac27f6df14629bf313",
|
|
7
|
+
"byteLength": 2285557,
|
|
8
|
+
"inputs": [
|
|
9
|
+
"extension/entries/content-entry.mjs",
|
|
10
|
+
"extension/src/content/activeTurnControl.js",
|
|
11
|
+
"extension/src/content/applyResultFormatters.js",
|
|
12
|
+
"extension/src/content/composerAttachments.js",
|
|
13
|
+
"extension/src/content/composerPanel.js",
|
|
14
|
+
"extension/src/content/contentRuntime.js",
|
|
15
|
+
"extension/src/content/contextTray.js",
|
|
16
|
+
"extension/src/content/diagnosticsController.js",
|
|
17
|
+
"extension/src/content/diagnosticsPanel.js",
|
|
18
|
+
"extension/src/content/diffReviewPanel.js",
|
|
19
|
+
"extension/src/content/legacyGlobalRegistry.js",
|
|
20
|
+
"extension/src/content/localSkillsPanel.js",
|
|
21
|
+
"extension/src/content/markdownDomRenderer.js",
|
|
22
|
+
"extension/src/content/markdownText.js",
|
|
23
|
+
"extension/src/content/mathText.js",
|
|
24
|
+
"extension/src/content/mirrorHealth.js",
|
|
25
|
+
"extension/src/content/modelPicker.js",
|
|
26
|
+
"extension/src/content/modelPickerSupport.js",
|
|
27
|
+
"extension/src/content/moduleRegistryKernel.js",
|
|
28
|
+
"extension/src/content/nativeChannel.js",
|
|
29
|
+
"extension/src/content/nativeCompatibilityController.js",
|
|
30
|
+
"extension/src/content/otWarmMirror.js",
|
|
31
|
+
"extension/src/content/otWarmMirrorController.js",
|
|
32
|
+
"extension/src/content/pageBridgeClient.js",
|
|
33
|
+
"extension/src/content/panelMaintenance.js",
|
|
34
|
+
"extension/src/content/panelRenderer.js",
|
|
35
|
+
"extension/src/content/pendingInputView.js",
|
|
36
|
+
"extension/src/content/postNavigationSettlementPersistence.js",
|
|
37
|
+
"extension/src/content/projectProviderSelection.js",
|
|
38
|
+
"extension/src/content/projectSessionCleanup.js",
|
|
39
|
+
"extension/src/content/projectSettingsCoordinator.js",
|
|
40
|
+
"extension/src/content/providerSettingsCoordinator.js",
|
|
41
|
+
"extension/src/content/providerSettingsDialog.js",
|
|
42
|
+
"extension/src/content/recentProjects.js",
|
|
43
|
+
"extension/src/content/reviewHunks.js",
|
|
44
|
+
"extension/src/content/runController.js",
|
|
45
|
+
"extension/src/content/runGuidanceController.js",
|
|
46
|
+
"extension/src/content/runGuidanceView.js",
|
|
47
|
+
"extension/src/content/runQueueScheduler.js",
|
|
48
|
+
"extension/src/content/runSettlementPersistence.js",
|
|
49
|
+
"extension/src/content/runTimelineView.js",
|
|
50
|
+
"extension/src/content/scopedPersistenceCoordinator.js",
|
|
51
|
+
"extension/src/content/scopedPersistenceDetachedCommit.js",
|
|
52
|
+
"extension/src/content/scopedPersistencePanelState.js",
|
|
53
|
+
"extension/src/content/sessionManager.js",
|
|
54
|
+
"extension/src/content/sessionMenuView.js",
|
|
55
|
+
"extension/src/content/sessionPanel.js",
|
|
56
|
+
"extension/src/content/sessionPersistence.js",
|
|
57
|
+
"extension/src/content/settingsPanel.js",
|
|
58
|
+
"extension/src/content/themeController.js",
|
|
59
|
+
"extension/src/content/updateIdle.js",
|
|
60
|
+
"extension/src/content/updateNotice.js",
|
|
61
|
+
"extension/src/content/writebackController.js",
|
|
62
|
+
"extension/src/content/writebackOrchestrator.js",
|
|
63
|
+
"extension/src/shared/agentTranscript.js",
|
|
64
|
+
"extension/src/shared/auditRecords.js",
|
|
65
|
+
"extension/src/shared/compatibility.js",
|
|
66
|
+
"extension/src/shared/compileAdapter.js",
|
|
67
|
+
"extension/src/shared/failureReasons.js",
|
|
68
|
+
"extension/src/shared/governanceRules.js",
|
|
69
|
+
"extension/src/shared/i18n.js",
|
|
70
|
+
"extension/src/shared/lineReferences.js",
|
|
71
|
+
"extension/src/shared/managedUpdateProjection.js",
|
|
72
|
+
"extension/src/shared/models.js",
|
|
73
|
+
"extension/src/shared/otText.js",
|
|
74
|
+
"extension/src/shared/pageRpcContract.js",
|
|
75
|
+
"extension/src/shared/pathRedaction.js",
|
|
76
|
+
"extension/src/shared/projectFiles.js",
|
|
77
|
+
"extension/src/shared/providerProfiles.js",
|
|
78
|
+
"extension/src/shared/reviewing.js",
|
|
79
|
+
"extension/src/shared/runExecutionSnapshot.js",
|
|
80
|
+
"extension/src/shared/runExecutionSnapshotCodec.js",
|
|
81
|
+
"extension/src/shared/runInputQueue.js",
|
|
82
|
+
"extension/src/shared/scopedPersistenceBrowserAdapter.js",
|
|
83
|
+
"extension/src/shared/scopedPersistenceQueuePolicy.js",
|
|
84
|
+
"extension/src/shared/scopedPersistenceReceipt.js",
|
|
85
|
+
"extension/src/shared/scopedPersistenceTransaction.js",
|
|
86
|
+
"extension/src/shared/sensitiveScan.js",
|
|
87
|
+
"extension/src/shared/sessionState.js",
|
|
88
|
+
"extension/src/shared/settlementFacts.js",
|
|
89
|
+
"extension/src/shared/staleGuard.js",
|
|
90
|
+
"extension/src/shared/storageDb.js",
|
|
91
|
+
"extension/src/shared/storageKeys.js",
|
|
92
|
+
"extension/src/shared/storageMigration.js",
|
|
93
|
+
"extension/src/shared/storageRunActions.js",
|
|
94
|
+
"extension/src/shared/storageSessionClaims.js",
|
|
95
|
+
"extension/src/shared/summary.js",
|
|
96
|
+
"extension/src/shared/undoOperations.js",
|
|
97
|
+
"extension/src/shared/writebackEvidenceProjection.js",
|
|
98
|
+
"extension/src/shared/writebackOperationEvidence.js",
|
|
99
|
+
"extension/src/shared/writebackSettlement.js",
|
|
100
|
+
"extension/vendor/katex/katex.min.js",
|
|
101
|
+
"extension/vendor/markdown-it/markdown-it.min.js"
|
|
102
|
+
]
|
|
103
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
(function initCodexOverleafLegacyGlobalRegistry(root, factory) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const api = factory();
|
|
5
|
+
if (typeof module === 'object' && module.exports) {
|
|
6
|
+
module.exports = api;
|
|
7
|
+
}
|
|
8
|
+
if (root) {
|
|
9
|
+
root.CodexOverleafLegacyGlobalRegistry = api;
|
|
10
|
+
}
|
|
11
|
+
})(typeof window !== 'undefined' ? window : globalThis, function legacyGlobalRegistryFactory() {
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const REQUIRED_MODULES = Object.freeze([
|
|
15
|
+
'ActiveTurnControl',
|
|
16
|
+
'AgentTranscript',
|
|
17
|
+
'ApplyResultFormatters',
|
|
18
|
+
'AuditRecords',
|
|
19
|
+
'Compatibility',
|
|
20
|
+
'ComposerAttachments',
|
|
21
|
+
'ComposerPanel',
|
|
22
|
+
'ContentRuntime',
|
|
23
|
+
'ContextTray',
|
|
24
|
+
'DiagnosticsController',
|
|
25
|
+
'DiagnosticsPanel',
|
|
26
|
+
'DiffReviewPanel',
|
|
27
|
+
'FailureReasons',
|
|
28
|
+
'GovernanceRules',
|
|
29
|
+
'I18n',
|
|
30
|
+
'LineReferences',
|
|
31
|
+
'LocalSkillsPanel',
|
|
32
|
+
'MarkdownText',
|
|
33
|
+
'MirrorHealth',
|
|
34
|
+
'ModelPicker',
|
|
35
|
+
'NativeChannel',
|
|
36
|
+
'NativeCompatibilityController',
|
|
37
|
+
'OtWarmMirror',
|
|
38
|
+
'OtWarmMirrorController',
|
|
39
|
+
'PageBridgeClient',
|
|
40
|
+
'PageRpcContract',
|
|
41
|
+
'PanelMaintenance',
|
|
42
|
+
'PanelRenderer',
|
|
43
|
+
'PendingInputView',
|
|
44
|
+
'PostNavigationSettlementPersistence',
|
|
45
|
+
'ProjectFiles',
|
|
46
|
+
'ProjectProviderSelection',
|
|
47
|
+
'ProjectSettingsCoordinator',
|
|
48
|
+
'ProviderSettingsCoordinator',
|
|
49
|
+
'RecentProjects',
|
|
50
|
+
'ReviewHunks',
|
|
51
|
+
'RunController',
|
|
52
|
+
'RunExecutionSnapshot',
|
|
53
|
+
'RunGuidanceController',
|
|
54
|
+
'RunInputQueue',
|
|
55
|
+
'RunQueueScheduler',
|
|
56
|
+
'RunSettlementPersistence',
|
|
57
|
+
'RunTimelineView',
|
|
58
|
+
'ScopedPersistenceCoordinator',
|
|
59
|
+
'ScopedPersistenceTransaction',
|
|
60
|
+
'SensitiveScan',
|
|
61
|
+
'SessionManager',
|
|
62
|
+
'SessionPanel',
|
|
63
|
+
'SessionPersistence',
|
|
64
|
+
'SessionState',
|
|
65
|
+
'SettingsPanel',
|
|
66
|
+
'StorageDb',
|
|
67
|
+
'StorageKeys',
|
|
68
|
+
'StorageMigration',
|
|
69
|
+
'Summary',
|
|
70
|
+
'Theme',
|
|
71
|
+
'UndoOperations',
|
|
72
|
+
'UpdateIdle',
|
|
73
|
+
'UpdateNotice',
|
|
74
|
+
'WritebackController',
|
|
75
|
+
'WritebackOrchestrator',
|
|
76
|
+
'WritebackSettlement'
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
const SUPPORT_MODULES = Object.freeze([
|
|
80
|
+
'CompileAdapter',
|
|
81
|
+
'MarkdownDomRenderer',
|
|
82
|
+
'MathText',
|
|
83
|
+
'ModelPickerSupport',
|
|
84
|
+
'ProjectSessionCleanup',
|
|
85
|
+
'ProviderProfiles',
|
|
86
|
+
'ProviderSettingsDialog',
|
|
87
|
+
'RunGuidanceView',
|
|
88
|
+
'SessionMenuView'
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
function create(root) {
|
|
92
|
+
if (!root || typeof root !== 'object') {
|
|
93
|
+
throw new TypeError('Codex Overleaf content startup requires a browser global.');
|
|
94
|
+
}
|
|
95
|
+
const modules = {};
|
|
96
|
+
const missing = [];
|
|
97
|
+
for (const name of [...REQUIRED_MODULES, ...SUPPORT_MODULES]) {
|
|
98
|
+
const value = root[`CodexOverleaf${name}`];
|
|
99
|
+
if (!value) {
|
|
100
|
+
missing.push(`CodexOverleaf${name}`);
|
|
101
|
+
} else {
|
|
102
|
+
modules[name] = value;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (missing.length) {
|
|
106
|
+
const error = new Error(`Codex Overleaf content dependencies are missing: ${missing.join(', ')}`);
|
|
107
|
+
error.code = 'content_dependency_missing';
|
|
108
|
+
error.missing = missing;
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
const vendor = Object.freeze({
|
|
112
|
+
katex: root.katex || null,
|
|
113
|
+
markdownit: root.markdownit || null
|
|
114
|
+
});
|
|
115
|
+
return Object.freeze({
|
|
116
|
+
root,
|
|
117
|
+
chromeApi: root.chrome,
|
|
118
|
+
document: root.document,
|
|
119
|
+
modules: Object.freeze(modules),
|
|
120
|
+
vendor
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return Object.freeze({
|
|
125
|
+
create,
|
|
126
|
+
requiredModules: REQUIRED_MODULES,
|
|
127
|
+
supportModules: SUPPORT_MODULES
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
(function initCodexOverleafMarkdownText() {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const LineReferences = window.CodexOverleafLineReferences;
|
|
5
|
-
|
|
6
4
|
// Markdown / assistant-text rendering — block + inline markdown, the
|
|
7
5
|
// assistant-visible sanitizers, and line-reference resolution/buttons carved
|
|
8
6
|
// out of contentRuntime.js (v1.4.5 structural-debt phase 1). The code below
|
|
@@ -10,15 +8,19 @@
|
|
|
10
8
|
// are factory-injected so behavior is unchanged.
|
|
11
9
|
function create(deps = {}) {
|
|
12
10
|
const {
|
|
11
|
+
LineReferences,
|
|
12
|
+
MathText,
|
|
13
13
|
tx,
|
|
14
|
-
callPageBridge,
|
|
14
|
+
callPageBridge, getCurrentProjectId,
|
|
15
15
|
getCurrentProjectReferenceFiles,
|
|
16
|
+
getCurrentProjectMathSources,
|
|
16
17
|
showPluginToast
|
|
17
18
|
} = deps;
|
|
18
19
|
|
|
19
20
|
function renderMarkdownInlineText(target, value) {
|
|
20
21
|
target.replaceChildren(...buildMarkdownInlineNodes(value));
|
|
21
22
|
}
|
|
23
|
+
function getMathMacros() { return MathText?.buildMathMacros?.(getCurrentProjectMathSources?.() || []) || {}; }
|
|
22
24
|
|
|
23
25
|
function sanitizeAssistantVisibleText(value) {
|
|
24
26
|
if (typeof value !== 'string' || !value) {
|
|
@@ -63,17 +65,12 @@
|
|
|
63
65
|
|
|
64
66
|
function buildMarkdownInlineNodes(value) {
|
|
65
67
|
const source = String(value || '');
|
|
66
|
-
const mathText =
|
|
67
|
-
? window.CodexOverleafMathText
|
|
68
|
-
: null;
|
|
68
|
+
const mathText = MathText;
|
|
69
69
|
if (!mathText?.buildMathNodes) {
|
|
70
70
|
return buildMarkdownInlineNodesWithoutMath(source);
|
|
71
71
|
}
|
|
72
|
-
return mathText.buildMathNodes(source, {
|
|
73
|
-
|
|
74
|
-
katex: window.katex,
|
|
75
|
-
renderText: buildMarkdownInlineNodesWithoutMath
|
|
76
|
-
});
|
|
72
|
+
return mathText.buildMathNodes(source, { document, katex: window.katex,
|
|
73
|
+
macros: getMathMacros(), renderText: buildMarkdownInlineNodesWithoutMath });
|
|
77
74
|
}
|
|
78
75
|
|
|
79
76
|
function buildMarkdownInlineNodesWithoutMath(value) {
|
|
@@ -111,6 +108,10 @@
|
|
|
111
108
|
function buildInlineCodeNodes(value) {
|
|
112
109
|
const source = String(value || '');
|
|
113
110
|
const trimmed = source.trim();
|
|
111
|
+
const standaloneMath = MathText?.parseStandaloneMath?.(trimmed);
|
|
112
|
+
if (standaloneMath && MathText?.createMathNode) return [MathText.createMathNode(
|
|
113
|
+
standaloneMath, { document, katex: window.katex, macros: getMathMacros() }
|
|
114
|
+
)];
|
|
114
115
|
const refs = trimmed ? parseRuntimeLineReferences(trimmed, 'plain-text-token') : [];
|
|
115
116
|
const ref = refs.length === 1 && refs[0]?.rawText === trimmed ? refs[0] : null;
|
|
116
117
|
if (ref && !isRuntimeLocalPathLike(ref.rawPath)) {
|
|
@@ -287,7 +288,7 @@
|
|
|
287
288
|
button.disabled = true;
|
|
288
289
|
button.dataset.status = 'pending';
|
|
289
290
|
try {
|
|
290
|
-
const result = await callPageBridge('jumpToPosition', params);
|
|
291
|
+
const result = await callPageBridge('jumpToPosition', { ...params, runProjectId: getCurrentProjectId?.() || '' });
|
|
291
292
|
if (result?.ok === false) {
|
|
292
293
|
button.dataset.status = 'failed';
|
|
293
294
|
button.title = tx('Could not open that referenced line.', '无法打开引用的行。');
|
|
@@ -494,12 +495,11 @@
|
|
|
494
495
|
`[${safeLabel.replace(/]/g, '\\]')}](${target.replace(/\)/g, '\\)')})`
|
|
495
496
|
);
|
|
496
497
|
},
|
|
497
|
-
renderCodeNodes: text =>
|
|
498
|
+
renderCodeNodes: text => buildInlineCodeNodes(text),
|
|
498
499
|
sanitizeText: sanitizeAssistantVisibleText,
|
|
499
|
-
createMathNode: segment => runtimeRoot.CodexOverleafMathText.createMathNode(segment,
|
|
500
|
-
document, katex: runtimeRoot.katex,
|
|
501
|
-
|
|
502
|
-
}),
|
|
500
|
+
createMathNode: segment => runtimeRoot.CodexOverleafMathText.createMathNode(segment,
|
|
501
|
+
{ document, katex: runtimeRoot.katex, macros: getMathMacros(),
|
|
502
|
+
renderText: text => buildMarkdownInlineNodes(text) }),
|
|
503
503
|
recordDiagnostic: recordRenderingDiagnostic
|
|
504
504
|
});
|
|
505
505
|
return;
|
|
@@ -9,6 +9,19 @@
|
|
|
9
9
|
]);
|
|
10
10
|
const LONG_INLINE_MATH_CHARS = 120;
|
|
11
11
|
const COMPLEX_INLINE_MATH_CHARS = 80;
|
|
12
|
+
const MAX_PROJECT_MACRO_SOURCES = 12;
|
|
13
|
+
const MAX_PROJECT_MACRO_SOURCE_CHARS = 256 * 1024;
|
|
14
|
+
const MAX_PROJECT_MACROS = 64;
|
|
15
|
+
const MAX_MACRO_EXPANSION_CHARS = 512;
|
|
16
|
+
const DEFAULT_MATH_MACROS = Object.freeze({
|
|
17
|
+
'\\E': '\\mathbb{E}',
|
|
18
|
+
'\\Var': '\\operatorname{Var}',
|
|
19
|
+
'\\Cov': '\\operatorname{Cov}',
|
|
20
|
+
'\\R': '\\mathbb{R}',
|
|
21
|
+
'\\N': '\\mathbb{N}',
|
|
22
|
+
'\\Z': '\\mathbb{Z}'
|
|
23
|
+
});
|
|
24
|
+
const UNSAFE_MACRO_PATTERN = /\\(?:href|url|includegraphics|input|include|write|openout|read|html\w*|class|style|data|def|gdef|edef|xdef|newcommand|renewcommand|providecommand|DeclareMathOperator)\b/i;
|
|
12
25
|
|
|
13
26
|
function parseMathSegments(value) {
|
|
14
27
|
const source = String(value || '');
|
|
@@ -74,9 +87,10 @@
|
|
|
74
87
|
searchFrom = start + delimiter.open.length;
|
|
75
88
|
continue;
|
|
76
89
|
}
|
|
77
|
-
const
|
|
90
|
+
const rawValue = source.slice(start + delimiter.open.length, closeStart);
|
|
91
|
+
const value = rawValue.trim();
|
|
78
92
|
const end = closeStart + delimiter.close.length;
|
|
79
|
-
if (!isValidMathValue(
|
|
93
|
+
if (!isValidMathValue(rawValue, delimiter) || overlapsCodeRange(start, end, codeRanges)) {
|
|
80
94
|
searchFrom = start + delimiter.open.length;
|
|
81
95
|
continue;
|
|
82
96
|
}
|
|
@@ -94,7 +108,7 @@
|
|
|
94
108
|
}
|
|
95
109
|
const previous = source[index - 1] || '';
|
|
96
110
|
const next = source[index + 1] || '';
|
|
97
|
-
return previous !== '$' && next !== '$' && next !== ''
|
|
111
|
+
return previous !== '$' && next !== '$' && next !== '';
|
|
98
112
|
}
|
|
99
113
|
|
|
100
114
|
function findClosingDelimiter(source, fromIndex, delimiter, codeRanges) {
|
|
@@ -107,7 +121,7 @@
|
|
|
107
121
|
const previous = source[index - 1] || '';
|
|
108
122
|
const next = source[index + delimiter.close.length] || '';
|
|
109
123
|
const invalidSingleDollar = delimiter.singleDollar
|
|
110
|
-
&& (previous === '$' || next === '$'
|
|
124
|
+
&& (previous === '$' || next === '$');
|
|
111
125
|
if (!isEscaped(source, index) && !isInsideRange(index, codeRanges) && !invalidSingleDollar) {
|
|
112
126
|
return index;
|
|
113
127
|
}
|
|
@@ -118,10 +132,24 @@
|
|
|
118
132
|
|
|
119
133
|
function isValidMathValue(value, delimiter) {
|
|
120
134
|
const source = String(value || '');
|
|
121
|
-
|
|
135
|
+
const trimmed = source.trim();
|
|
136
|
+
if (!trimmed) {
|
|
122
137
|
return false;
|
|
123
138
|
}
|
|
124
|
-
|
|
139
|
+
if (!delimiter.display && /[\r\n]/.test(source)) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
if (!delimiter.singleDollar || (!/^\s/.test(source) && !/\s$/.test(source))) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
return looksLikeWhitespaceWrappedMath(trimmed);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function looksLikeWhitespaceWrappedMath(value) {
|
|
149
|
+
const source = String(value || '').trim();
|
|
150
|
+
return /\\[A-Za-z]+/.test(source)
|
|
151
|
+
|| /[_^=<>+\-*/()[\]{}|]/.test(source)
|
|
152
|
+
|| /^[A-Za-z](?:_[A-Za-z0-9{}]+|\^[A-Za-z0-9{}]+)?$/.test(source);
|
|
125
153
|
}
|
|
126
154
|
|
|
127
155
|
function collectInlineCodeRanges(source) {
|
|
@@ -179,7 +207,8 @@
|
|
|
179
207
|
}
|
|
180
208
|
nodes.push(createMathNode(segment, {
|
|
181
209
|
document: documentRef,
|
|
182
|
-
katex: options.katex || root.katex
|
|
210
|
+
katex: options.katex || root.katex,
|
|
211
|
+
macros: options.macros || buildMathMacros(options.projectSources)
|
|
183
212
|
}));
|
|
184
213
|
}
|
|
185
214
|
return nodes;
|
|
@@ -206,6 +235,7 @@
|
|
|
206
235
|
strict: 'warn',
|
|
207
236
|
maxExpand: 200,
|
|
208
237
|
maxSize: 20,
|
|
238
|
+
macros: options.macros || buildMathMacros(),
|
|
209
239
|
output: 'htmlAndMathml'
|
|
210
240
|
});
|
|
211
241
|
node.dataset.mathRendered = 'true';
|
|
@@ -213,7 +243,7 @@
|
|
|
213
243
|
} catch (_error) {
|
|
214
244
|
node.classList.add('run-math--fallback');
|
|
215
245
|
node.dataset.mathRendered = 'false';
|
|
216
|
-
node.textContent =
|
|
246
|
+
node.textContent = source;
|
|
217
247
|
return node;
|
|
218
248
|
}
|
|
219
249
|
}
|
|
@@ -235,6 +265,120 @@
|
|
|
235
265
|
return /(?:=|\\(?:le|ge|approx|sim|to|Rightarrow|Longrightarrow)\b|\\begin\{(?:aligned|gathered|split|array)\}|\\\\)/.test(source);
|
|
236
266
|
}
|
|
237
267
|
|
|
268
|
+
function parseStandaloneMath(value) {
|
|
269
|
+
const source = String(value || '').trim();
|
|
270
|
+
if (!source) {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
const segments = parseMathSegments(source);
|
|
274
|
+
if (segments.length !== 1 || segments[0].type !== 'math' || segments[0].raw !== source) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
return segments[0];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function buildMathMacros(projectSources = []) {
|
|
281
|
+
const macros = { ...DEFAULT_MATH_MACROS };
|
|
282
|
+
let remainingChars = MAX_PROJECT_MACRO_SOURCE_CHARS;
|
|
283
|
+
let projectMacroCount = 0;
|
|
284
|
+
for (const sourceRecord of Array.isArray(projectSources)
|
|
285
|
+
? projectSources.slice(0, MAX_PROJECT_MACRO_SOURCES)
|
|
286
|
+
: []) {
|
|
287
|
+
if (projectMacroCount >= MAX_PROJECT_MACROS || remainingChars <= 0) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
const path = String(sourceRecord?.path || '');
|
|
291
|
+
if (!/\.(?:tex|sty|cls|ltx)$/i.test(path)) {
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
const source = stripLatexComments(
|
|
295
|
+
String(sourceRecord?.content || '').slice(0, remainingChars)
|
|
296
|
+
);
|
|
297
|
+
remainingChars -= source.length;
|
|
298
|
+
const pattern = /\\(newcommand|renewcommand|providecommand|DeclareMathOperator)(\*)?/g;
|
|
299
|
+
let match;
|
|
300
|
+
while ((match = pattern.exec(source)) !== null && projectMacroCount < MAX_PROJECT_MACROS) {
|
|
301
|
+
let cursor = skipWhitespace(source, pattern.lastIndex);
|
|
302
|
+
const nameGroup = readBracedGroup(source, cursor);
|
|
303
|
+
if (!nameGroup) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
const macroName = nameGroup.value.trim();
|
|
307
|
+
cursor = skipWhitespace(source, nameGroup.end);
|
|
308
|
+
if (source[cursor] === '[') {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const expansionGroup = readBracedGroup(source, cursor);
|
|
312
|
+
if (!expansionGroup) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
let expansion = expansionGroup.value.trim();
|
|
316
|
+
if (match[1] === 'DeclareMathOperator') {
|
|
317
|
+
expansion = `\\operatorname${match[2] ? '*' : ''}{${expansion}}`;
|
|
318
|
+
}
|
|
319
|
+
if (!isSafeMacroDefinition(macroName, expansion)) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
macros[macroName] = expansion;
|
|
323
|
+
projectMacroCount++;
|
|
324
|
+
pattern.lastIndex = expansionGroup.end;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return macros;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function readBracedGroup(source, start) {
|
|
331
|
+
if (source[start] !== '{') {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
let depth = 0;
|
|
335
|
+
for (let index = start; index < source.length; index++) {
|
|
336
|
+
if (source[index] === '{' && !isEscaped(source, index)) {
|
|
337
|
+
depth++;
|
|
338
|
+
} else if (source[index] === '}' && !isEscaped(source, index)) {
|
|
339
|
+
depth--;
|
|
340
|
+
if (depth === 0) {
|
|
341
|
+
return {
|
|
342
|
+
value: source.slice(start + 1, index),
|
|
343
|
+
end: index + 1
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function skipWhitespace(source, start) {
|
|
352
|
+
let index = start;
|
|
353
|
+
while (index < source.length && /\s/.test(source[index])) {
|
|
354
|
+
index++;
|
|
355
|
+
}
|
|
356
|
+
return index;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function stripLatexComments(source) {
|
|
360
|
+
return String(source || '').split(/\r?\n/).map(line => {
|
|
361
|
+
for (let index = 0; index < line.length; index++) {
|
|
362
|
+
if (line[index] === '%' && !isEscaped(line, index)) {
|
|
363
|
+
return line.slice(0, index);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return line;
|
|
367
|
+
}).join('\n');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function isSafeMacroDefinition(name, expansion) {
|
|
371
|
+
const macroName = String(name || '');
|
|
372
|
+
const body = String(expansion || '');
|
|
373
|
+
return /^\\[A-Za-z@]+$/.test(macroName)
|
|
374
|
+
&& body.length > 0
|
|
375
|
+
&& body.length <= MAX_MACRO_EXPANSION_CHARS
|
|
376
|
+
&& !body.includes('#')
|
|
377
|
+
&& !body.includes(macroName)
|
|
378
|
+
&& !UNSAFE_MACRO_PATTERN.test(macroName)
|
|
379
|
+
&& !UNSAFE_MACRO_PATTERN.test(body);
|
|
380
|
+
}
|
|
381
|
+
|
|
238
382
|
function toNodeArray(value) {
|
|
239
383
|
if (Array.isArray(value)) {
|
|
240
384
|
return value;
|
|
@@ -265,11 +409,13 @@
|
|
|
265
409
|
}
|
|
266
410
|
|
|
267
411
|
const api = {
|
|
412
|
+
buildMathMacros,
|
|
268
413
|
buildMathNodes,
|
|
269
414
|
createMathNode,
|
|
270
415
|
matchMathAt,
|
|
271
416
|
normalizeMathForRendering,
|
|
272
|
-
parseMathSegments
|
|
417
|
+
parseMathSegments,
|
|
418
|
+
parseStandaloneMath
|
|
273
419
|
};
|
|
274
420
|
root.CodexOverleafMathText = api;
|
|
275
421
|
if (typeof module !== 'undefined' && module.exports) {
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
(function initCodexOverleafModelPickerSupport(root) {
|
|
1
|
+
(function initCodexOverleafModelPickerSupport(root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) {
|
|
3
|
+
module.exports = factory(require('../shared/models'));
|
|
4
|
+
} else {
|
|
5
|
+
root.CodexOverleafModuleRegistry.define('ModelPickerSupport', ['Models'], factory);
|
|
6
|
+
}
|
|
7
|
+
})(typeof window !== 'undefined' ? window : globalThis, function modelPickerSupportFactory(Models) {
|
|
2
8
|
'use strict';
|
|
3
9
|
|
|
4
10
|
function normalizeModelOptionId(id) {
|
|
@@ -37,7 +43,7 @@
|
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
function getModelCatalog({ getPanel } = {}) {
|
|
40
|
-
const shared =
|
|
46
|
+
const shared = Models;
|
|
41
47
|
if (Array.isArray(shared?.FALLBACK_MODELS) && typeof shared?.normalizeDiscoveredModels === 'function') {
|
|
42
48
|
return shared;
|
|
43
49
|
}
|
|
@@ -110,6 +116,5 @@
|
|
|
110
116
|
retainSelectedModel,
|
|
111
117
|
shouldUseBuiltInFallback
|
|
112
118
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
})(typeof window !== 'undefined' ? window : globalThis);
|
|
119
|
+
return api;
|
|
120
|
+
});
|