@atlaskit/editor-plugin-code-block 14.0.6 → 14.1.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/CHANGELOG.md +33 -0
- package/dist/cjs/codeBlockPlugin.js +2 -3
- package/dist/cjs/editor-commands/index.js +3 -0
- package/dist/cjs/pm-plugins/main.js +3 -2
- package/dist/cjs/pm-plugins/toolbar.js +6 -4
- package/dist/cjs/ui/CodeBlockLanguagePicker.js +13 -3
- package/dist/cjs/ui/CodeBlockMenuItem.js +7 -2
- package/dist/cjs/ui/LanguagePicker.js +72 -12
- package/dist/cjs/utils/auto-detect-view.js +21 -11
- package/dist/cjs/utils/language-detect.js +5 -1
- package/dist/es2019/codeBlockPlugin.js +2 -3
- package/dist/es2019/editor-commands/index.js +3 -0
- package/dist/es2019/pm-plugins/main.js +3 -2
- package/dist/es2019/pm-plugins/toolbar.js +6 -4
- package/dist/es2019/ui/CodeBlockLanguagePicker.js +13 -3
- package/dist/es2019/ui/CodeBlockMenuItem.js +8 -3
- package/dist/es2019/ui/LanguagePicker.js +61 -7
- package/dist/es2019/utils/auto-detect-view.js +22 -11
- package/dist/es2019/utils/language-detect.js +3 -2
- package/dist/esm/codeBlockPlugin.js +2 -3
- package/dist/esm/editor-commands/index.js +3 -0
- package/dist/esm/pm-plugins/main.js +3 -2
- package/dist/esm/pm-plugins/toolbar.js +6 -4
- package/dist/esm/ui/CodeBlockLanguagePicker.js +13 -3
- package/dist/esm/ui/CodeBlockMenuItem.js +7 -2
- package/dist/esm/ui/LanguagePicker.js +72 -12
- package/dist/esm/utils/auto-detect-view.js +21 -11
- package/dist/esm/utils/language-detect.js +5 -2
- package/dist/types/ui/CodeBlockLanguagePicker.d.ts +1 -1
- package/dist/types/ui/CodeBlockMenuItem.d.ts +2 -1
- package/dist/types/ui/LanguagePicker.d.ts +2 -1
- package/package.json +11 -8
|
@@ -6,7 +6,8 @@ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
|
6
6
|
import AngleBracketsIcon from '@atlaskit/icon/core/angle-brackets';
|
|
7
7
|
const NODE_NAME = 'codeBlock';
|
|
8
8
|
const CodeBlockMenuItem = ({
|
|
9
|
-
api
|
|
9
|
+
api,
|
|
10
|
+
isSuggested
|
|
10
11
|
}) => {
|
|
11
12
|
const {
|
|
12
13
|
formatMessage
|
|
@@ -20,6 +21,7 @@ const CodeBlockMenuItem = ({
|
|
|
20
21
|
var _api$blockMenu;
|
|
21
22
|
const command = api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.commands.transformNode(tr.doc.type.schema.nodes.codeBlock, {
|
|
22
23
|
inputMethod,
|
|
24
|
+
isSuggested,
|
|
23
25
|
triggeredFrom,
|
|
24
26
|
targetTypeName: NODE_NAME
|
|
25
27
|
});
|
|
@@ -37,7 +39,10 @@ const CodeBlockMenuItem = ({
|
|
|
37
39
|
}, formatMessage(blockMenuMessages.codeBlock));
|
|
38
40
|
};
|
|
39
41
|
export const createCodeBlockMenuItem = api => {
|
|
40
|
-
return (
|
|
41
|
-
|
|
42
|
+
return ({
|
|
43
|
+
isSuggested
|
|
44
|
+
} = {}) => /*#__PURE__*/React.createElement(CodeBlockMenuItem, {
|
|
45
|
+
api: api,
|
|
46
|
+
isSuggested: isSuggested
|
|
42
47
|
});
|
|
43
48
|
};
|
|
@@ -6,6 +6,7 @@ import Button from '@atlaskit/button/new';
|
|
|
6
6
|
import { codeBlockButtonMessages } from '@atlaskit/editor-common/messages';
|
|
7
7
|
import { akEditorLineHeight } from '@atlaskit/editor-shared-styles';
|
|
8
8
|
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
|
|
9
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
9
10
|
import { Box } from '@atlaskit/primitives/compiled';
|
|
10
11
|
import { PopupSelect, components } from '@atlaskit/select';
|
|
11
12
|
import { createGroupedLanguageOptions } from './language-picker-options';
|
|
@@ -47,6 +48,11 @@ const menuPopperProps = {
|
|
|
47
48
|
enabled: false
|
|
48
49
|
}]
|
|
49
50
|
};
|
|
51
|
+
const focusWithoutScrolling = element => {
|
|
52
|
+
element.focus({
|
|
53
|
+
preventScroll: true
|
|
54
|
+
});
|
|
55
|
+
};
|
|
50
56
|
const getRecentlyUsedLanguages = (recentLanguageValues, optionsByValue) => {
|
|
51
57
|
const recentlyUsedLanguages = [];
|
|
52
58
|
for (const recentLanguageValue of recentLanguageValues) {
|
|
@@ -64,12 +70,14 @@ export const LanguagePicker = ({
|
|
|
64
70
|
languagePickerOptions,
|
|
65
71
|
recentLanguageValues = [],
|
|
66
72
|
onMenuOpen,
|
|
67
|
-
onSelection
|
|
73
|
+
onSelection,
|
|
74
|
+
triggerSpacing = 'default'
|
|
68
75
|
}) => {
|
|
69
76
|
var _defaultValue$label;
|
|
70
77
|
const label = (_defaultValue$label = defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.label) !== null && _defaultValue$label !== void 0 ? _defaultValue$label : formatMessage(codeBlockButtonMessages.selectLanguage);
|
|
71
78
|
const selectLanguageLabel = formatMessage(codeBlockButtonMessages.selectLanguage);
|
|
72
79
|
const [hasSearchQuery, setHasSearchQuery] = useState(false);
|
|
80
|
+
const [lockedPopperPlacement, setLockedPopperPlacement] = useState();
|
|
73
81
|
const inputValueRef = useRef('');
|
|
74
82
|
const optionsByValue = useMemo(() => new Map(languagePickerOptions.map(option => [option.value, option])), [languagePickerOptions]);
|
|
75
83
|
const recentlyUsedLanguages = useMemo(() => getRecentlyUsedLanguages(recentLanguageValues, optionsByValue), [recentLanguageValues, optionsByValue]);
|
|
@@ -79,6 +87,28 @@ export const LanguagePicker = ({
|
|
|
79
87
|
recentlyUsedLanguages
|
|
80
88
|
}), [formatMessage, languagePickerOptions, recentlyUsedLanguages]);
|
|
81
89
|
const searchOptions = useMemo(() => options.flatMap(group => group.options), [options]);
|
|
90
|
+
const stableMenuPopperProps = useMemo(() => ({
|
|
91
|
+
// Allow Popper to choose top on the first open when bottom has no room, then lock the
|
|
92
|
+
// chosen placement so later hover/search renders do not move the open picker.
|
|
93
|
+
placement: lockedPopperPlacement !== null && lockedPopperPlacement !== void 0 ? lockedPopperPlacement : 'bottom-start',
|
|
94
|
+
modifiers: [{
|
|
95
|
+
name: 'offset',
|
|
96
|
+
options: {
|
|
97
|
+
offset: [0, 8]
|
|
98
|
+
}
|
|
99
|
+
}, {
|
|
100
|
+
name: 'preventOverflow',
|
|
101
|
+
enabled: false
|
|
102
|
+
}, ...(lockedPopperPlacement ? [{
|
|
103
|
+
name: 'flip',
|
|
104
|
+
enabled: false
|
|
105
|
+
}] : [])],
|
|
106
|
+
onFirstUpdate: ({
|
|
107
|
+
placement
|
|
108
|
+
}) => {
|
|
109
|
+
setLockedPopperPlacement(placement);
|
|
110
|
+
}
|
|
111
|
+
}), [lockedPopperPlacement]);
|
|
82
112
|
const handleChange = useCallback(option => {
|
|
83
113
|
var _option$selectionSour;
|
|
84
114
|
if (!option) {
|
|
@@ -91,11 +121,33 @@ export const LanguagePicker = ({
|
|
|
91
121
|
const handleInputChange = useCallback((newInputValue, actionMeta) => {
|
|
92
122
|
// React-select clears the input as part of selecting a value before onChange fires.
|
|
93
123
|
// Keep the last user-typed query so handleChange can report search selections correctly.
|
|
94
|
-
|
|
124
|
+
const isInputChange = !actionMeta || actionMeta.action === 'input-change';
|
|
125
|
+
if (isInputChange) {
|
|
95
126
|
inputValueRef.current = newInputValue;
|
|
96
127
|
}
|
|
97
|
-
|
|
98
|
-
|
|
128
|
+
if (isInputChange || !fg('platform_editor_code_block_dogfooding_patch')) {
|
|
129
|
+
setHasSearchQuery(newInputValue.trim().length > 0);
|
|
130
|
+
return newInputValue;
|
|
131
|
+
}
|
|
132
|
+
return inputValueRef.current;
|
|
133
|
+
}, []);
|
|
134
|
+
const handleMenuOpen = useCallback(() => {
|
|
135
|
+
if (fg('platform_editor_code_block_dogfooding_patch')) {
|
|
136
|
+
inputValueRef.current = '';
|
|
137
|
+
setHasSearchQuery(false);
|
|
138
|
+
setLockedPopperPlacement(undefined);
|
|
139
|
+
}
|
|
140
|
+
onMenuOpen === null || onMenuOpen === void 0 ? void 0 : onMenuOpen();
|
|
141
|
+
}, [onMenuOpen]);
|
|
142
|
+
const handleTriggerMouseDown = useCallback(event => {
|
|
143
|
+
if (fg('platform_editor_code_block_dogfooding_patch')) {
|
|
144
|
+
// PopupSelect's FocusLock returns focus to the element that was focused before the
|
|
145
|
+
// picker opened. If that is the editor/code block, closing the picker can scroll the
|
|
146
|
+
// whole code block into view. Focus the trigger first without scrolling so FocusLock
|
|
147
|
+
// returns to the trigger; see CodeBlockLanguagePicker's handleSelection for restoring
|
|
148
|
+
// editor focus.
|
|
149
|
+
focusWithoutScrolling(event.currentTarget);
|
|
150
|
+
}
|
|
99
151
|
}, []);
|
|
100
152
|
const renderTarget = useCallback(({
|
|
101
153
|
isOpen,
|
|
@@ -105,7 +157,9 @@ export const LanguagePicker = ({
|
|
|
105
157
|
}) => /*#__PURE__*/React.createElement("div", {
|
|
106
158
|
className: ax([styles.trigger])
|
|
107
159
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
160
|
+
spacing: triggerSpacing,
|
|
108
161
|
shouldFitContainer: true,
|
|
162
|
+
onMouseDown: handleTriggerMouseDown,
|
|
109
163
|
onKeyDown: onKeyDown,
|
|
110
164
|
ref: ref,
|
|
111
165
|
iconAfter: ChevronDownIcon,
|
|
@@ -113,7 +167,7 @@ export const LanguagePicker = ({
|
|
|
113
167
|
isSelected: isOpen,
|
|
114
168
|
"aria-controls": ariaControls,
|
|
115
169
|
testId: "code-block-language-picker-trigger"
|
|
116
|
-
}, label)), [label]);
|
|
170
|
+
}, label)), [label, triggerSpacing, handleTriggerMouseDown]);
|
|
117
171
|
return /*#__PURE__*/React.createElement(PopupSelect, {
|
|
118
172
|
components: popupSelectComponents,
|
|
119
173
|
filterOption: filterOption,
|
|
@@ -123,9 +177,9 @@ export const LanguagePicker = ({
|
|
|
123
177
|
menuPlacement: "auto",
|
|
124
178
|
onChange: handleChange,
|
|
125
179
|
onInputChange: handleInputChange,
|
|
126
|
-
onMenuOpen:
|
|
180
|
+
onMenuOpen: handleMenuOpen,
|
|
127
181
|
options: hasSearchQuery ? searchOptions : options,
|
|
128
|
-
popperProps: menuPopperProps,
|
|
182
|
+
popperProps: fg('platform_editor_code_block_dogfooding_patch') ? stableMenuPopperProps : menuPopperProps,
|
|
129
183
|
searchThreshold: -1,
|
|
130
184
|
target: renderTarget,
|
|
131
185
|
testId: "code-block-language-picker",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
3
|
import { ACTIONS } from '../pm-plugins/actions';
|
|
3
4
|
import { autoDetectPluginKey } from '../pm-plugins/auto-detect-state';
|
|
4
5
|
import { createAutoDetectEntry } from './auto-detect-state';
|
|
@@ -32,6 +33,7 @@ const runPendingDetection = (view, localId, api) => {
|
|
|
32
33
|
}
|
|
33
34
|
const detectedLanguage = detectLanguage(found.node.textContent);
|
|
34
35
|
const detectionResult = detectedLanguage ? 'detected' : 'noneDetected';
|
|
36
|
+
const detectionPhase = entry.detectionResult ? 'redetection' : 'initial';
|
|
35
37
|
// Keep a previous auto-detected language when the latest snippet is too weak to classify.
|
|
36
38
|
const shouldPreserveAutoDetectedLanguage = !detectedLanguage && Boolean(entry.autoDetectedLanguage) && found.node.attrs.language === entry.autoDetectedLanguage;
|
|
37
39
|
const nextEntry = {
|
|
@@ -42,11 +44,13 @@ const runPendingDetection = (view, localId, api) => {
|
|
|
42
44
|
|
|
43
45
|
// If there is no confident detection, record the result without clearing user-visible language.
|
|
44
46
|
const shouldOnlyUpdateDetectionState = !detectedLanguage && (!found.node.attrs.language || shouldPreserveAutoDetectedLanguage);
|
|
47
|
+
const hasDetectedLanguageChange = Boolean(detectedLanguage) && found.node.attrs.language !== detectedLanguage;
|
|
48
|
+
const shouldClearStaleLanguage = !detectedLanguage && Boolean(found.node.attrs.language) && !shouldPreserveAutoDetectedLanguage;
|
|
49
|
+
const shouldUpdateNodeLanguage = fg('platform_editor_code_block_dogfooding_patch') ? hasDetectedLanguageChange || shouldClearStaleLanguage : !shouldOnlyUpdateDetectionState;
|
|
45
50
|
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
|
|
46
51
|
tr
|
|
47
52
|
}) => {
|
|
48
|
-
|
|
49
|
-
if (!shouldOnlyUpdateDetectionState) {
|
|
53
|
+
if (shouldUpdateNodeLanguage) {
|
|
50
54
|
tr.setNodeMarkup(found.pos, undefined, {
|
|
51
55
|
...found.node.attrs,
|
|
52
56
|
language: detectedLanguage
|
|
@@ -59,15 +63,22 @@ const runPendingDetection = (view, localId, api) => {
|
|
|
59
63
|
entry: nextEntry
|
|
60
64
|
}
|
|
61
65
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
// When platform_editor_code_block_dogfooding_patch is cleaned up, merge this with the previous shouldUpdateNodeLanguage check.
|
|
67
|
+
if (!fg('platform_editor_code_block_dogfooding_patch') || shouldUpdateNodeLanguage) {
|
|
68
|
+
var _api$analytics;
|
|
69
|
+
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.attachAnalyticsEvent({
|
|
70
|
+
action: ACTION.LANGUAGE_AUTO_DETECTED,
|
|
71
|
+
actionSubject: ACTION_SUBJECT.CODE_BLOCK,
|
|
72
|
+
attributes: {
|
|
73
|
+
language: detectedLanguage !== null && detectedLanguage !== void 0 ? detectedLanguage : 'none',
|
|
74
|
+
detectionResult,
|
|
75
|
+
...(fg('platform_editor_code_block_dogfooding_patch') ? {
|
|
76
|
+
detectionPhase
|
|
77
|
+
} : {})
|
|
78
|
+
},
|
|
79
|
+
eventType: EVENT_TYPE.TRACK
|
|
80
|
+
})(tr);
|
|
81
|
+
}
|
|
71
82
|
// Language detection runs in the background and should not move the viewport.
|
|
72
83
|
return tr.setMeta('scrollIntoView', false);
|
|
73
84
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable require-unicode-regexp */
|
|
2
|
-
|
|
2
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
3
|
// Conservative weighted-regex heuristic for common high-confidence snippets, not a full classifier.
|
|
4
4
|
// Ambiguous snippets intentionally return null so users can select the language manually.
|
|
5
5
|
const MAX_DETECTION_CHARS = 10_000;
|
|
@@ -12,6 +12,7 @@ const hasPattern = (code, pattern) => {
|
|
|
12
12
|
return pattern.test(code);
|
|
13
13
|
};
|
|
14
14
|
const scorePatterns = (code, patterns) => patterns.reduce((score, [pattern, value]) => score + (hasPattern(code, pattern) ? value : 0), 0);
|
|
15
|
+
const scoreEnhancedTypeScriptPatterns = code => fg('platform_editor_code_block_dogfooding_patch') ? scorePatterns(code, [[/\b(?:private|protected|public|readonly)\s+[\w$]+\s*=/, 5], [/\([^)]{0,500}\b[\w$]+\??:\s*[A-Za-z_$][\w$<>{}\[\]|&,\s.?]{0,200}[^)]{0,500}\)\s*(?::\s*[A-Za-z_$][\w$<>{}\[\]|&,\s.?]{0,200})?\s*=>/, 5]]) : 0;
|
|
15
16
|
const looksLikeHtmlTagPair = code => {
|
|
16
17
|
const openTags = new Set();
|
|
17
18
|
const tagPattern = /<\/?([a-z][a-z0-9-]*)\b[^<>]{0,500}>/gi;
|
|
@@ -57,7 +58,7 @@ const getLanguageScores = code => [{
|
|
|
57
58
|
score: scorePatterns(code, [[/\bSELECT\b[\s\S]+\bFROM\b/i, 5], [/\b(?:INSERT\s+INTO|UPDATE\b[\s\S]+\bSET\b|DELETE\s+FROM|CREATE\s+TABLE|ALTER\s+TABLE)\b/i, 5], [/\b(?:JOIN|WHERE|GROUP\s+BY|ORDER\s+BY|LIMIT)\b/i, 2]])
|
|
58
59
|
}, {
|
|
59
60
|
language: 'typescript',
|
|
60
|
-
score: scorePatterns(code, [[/\b(?:interface|type)\s+[A-Z_$][\w$]*(?:\s*[=<{])/, 5], [/\bimport\s+type\b|\bexport\s+type\b/, 4], [/\b(?:const|let|var)\s+[\w$]+\s*:\s*[A-Za-z_$][\w$<>|\[\],\s]*/, 4], [/\)\s*:\s*(?:Promise<)?[A-Za-z_$][\w$<>|\[\],\s]*(?:>|\s)?\s*=>?\s*[{;]/, 3], [/\b(?:as\s+const|implements\s+[A-Z_$]|enum\s+[A-Z_$])/, 3]])
|
|
61
|
+
score: scorePatterns(code, [[/\b(?:interface|type)\s+[A-Z_$][\w$]*(?:\s*[=<{])/, 5], [/\bimport\s+type\b|\bexport\s+type\b/, 4], [/\b(?:const|let|var)\s+[\w$]+\s*:\s*[A-Za-z_$][\w$<>|\[\],\s]*/, 4], [/\)\s*:\s*(?:Promise<)?[A-Za-z_$][\w$<>|\[\],\s]*(?:>|\s)?\s*=>?\s*[{;]/, 3], [/\b(?:as\s+const|implements\s+[A-Z_$]|enum\s+[A-Z_$])/, 3]]) + scoreEnhancedTypeScriptPatterns(code)
|
|
61
62
|
}, {
|
|
62
63
|
language: 'javascript',
|
|
63
64
|
score: scorePatterns(code, [[/\b(?:const|let|var)\s+[\w$]+\s*=/, 3], [/\bfunction\s*[\w$]*\s*\([^)]*\)\s*\{/, 3], [/=>\s*(?:\{|[\w$'"`(])/, 3], [/\b(?:import|export)\s+(?:[\w${}*,\s]+\s+from\s+)?['"][^'"]+['"]/, 3], [/\b(?:console\.log|document\.|window\.|require\()|\bmodule\.exports\b/, 3]])
|
|
@@ -9,7 +9,6 @@ import { TRANSFORM_STRUCTURE_MENU_SECTION, TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_I
|
|
|
9
9
|
import { blockTypeMessages } from '@atlaskit/editor-common/messages';
|
|
10
10
|
import { IconCode } from '@atlaskit/editor-common/quick-insert';
|
|
11
11
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
12
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
12
|
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
14
13
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
15
14
|
import { createInsertCodeBlockTransaction, insertCodeBlockWithAnalytics } from './editor-commands';
|
|
@@ -51,7 +50,7 @@ var codeBlockPlugin = function codeBlockPlugin(_ref) {
|
|
|
51
50
|
nodes: function nodes() {
|
|
52
51
|
return [{
|
|
53
52
|
name: 'codeBlock',
|
|
54
|
-
node:
|
|
53
|
+
node: expValEqualsNoExposure('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? codeBlock : fg('platform_editor_adf_with_localid') ? codeBlockWithLocalId : codeBlock
|
|
55
54
|
}];
|
|
56
55
|
},
|
|
57
56
|
getSharedState: function getSharedState(state) {
|
|
@@ -83,7 +82,7 @@ var codeBlockPlugin = function codeBlockPlugin(_ref) {
|
|
|
83
82
|
var schema = _ref3.schema;
|
|
84
83
|
return createCodeBlockInputRule(schema, api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
85
84
|
}
|
|
86
|
-
}].concat(_toConsumableArray(
|
|
85
|
+
}].concat(_toConsumableArray(expValEqualsNoExposure('platform_editor_code_block_q4_lovability', 'isEnabled', true) && fg('platform_editor_code_block_language_detection_flow') ? [{
|
|
87
86
|
name: 'codeBlockAutoDetect',
|
|
88
87
|
plugin: function plugin() {
|
|
89
88
|
return createAutoDetectPlugin(api);
|
|
@@ -472,6 +472,9 @@ export var toggleWordWrapStateForCodeBlockNode = function toggleWordWrapStateFor
|
|
|
472
472
|
tr.setNodeMarkup(codeBlock.pos, undefined, _objectSpread(_objectSpread({}, codeBlockNode.attrs), {}, {
|
|
473
473
|
wrap: updatedToggleState
|
|
474
474
|
}));
|
|
475
|
+
if (fg('platform_editor_code_block_dogfooding_patch')) {
|
|
476
|
+
tr.setMeta('scrollIntoView', false);
|
|
477
|
+
}
|
|
475
478
|
} else {
|
|
476
479
|
codeBlockWrappedStates.set(codeBlockNode, updatedToggleState);
|
|
477
480
|
}
|
|
@@ -10,6 +10,7 @@ import { findCodeBlock } from '@atlaskit/editor-common/transforms';
|
|
|
10
10
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
11
11
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
12
12
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
|
+
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
13
14
|
import { ignoreFollowingMutations, resetShouldIgnoreFollowingMutations } from '../editor-commands';
|
|
14
15
|
import { codeBlockNodeView } from '../nodeviews/code-block';
|
|
15
16
|
import { codeBlockClassNames } from '../ui/class-names';
|
|
@@ -123,7 +124,7 @@ export var createPlugin = function createPlugin(_ref) {
|
|
|
123
124
|
isNodeSelected: tr.selection instanceof NodeSelection,
|
|
124
125
|
decorations: updatedDecorationSet
|
|
125
126
|
});
|
|
126
|
-
if (!
|
|
127
|
+
if (!expValEqualsNoExposure('platform_editor_code_block_q4_lovability', 'isEnabled', true)) {
|
|
127
128
|
return newPluginState;
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -151,7 +152,7 @@ export var createPlugin = function createPlugin(_ref) {
|
|
|
151
152
|
shouldIgnoreFollowingMutations: meta.data
|
|
152
153
|
});
|
|
153
154
|
}
|
|
154
|
-
if (
|
|
155
|
+
if (expValEqualsNoExposure('platform_editor_code_block_q4_lovability', 'isEnabled', true)) {
|
|
155
156
|
// Failed/unchanged format results and dismissals are meta-only.
|
|
156
157
|
return applyFormatCodeMeta(pluginState, meta);
|
|
157
158
|
}
|
|
@@ -14,6 +14,7 @@ import ListNumberedIcon from '@atlaskit/icon/core/list-numbered';
|
|
|
14
14
|
import TextWrapIcon from '@atlaskit/icon/core/text-wrap';
|
|
15
15
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
16
16
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
17
|
+
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
17
18
|
import { changeLanguage, copyContentToClipboardWithAnalytics, createFormatCodeOnClick, removeCodeBlockWithAnalytics, resetCopiedState, toggleLineNumbersForCodeBlockNode, toggleWordWrapStateForCodeBlockNode } from '../editor-commands';
|
|
18
19
|
import { CodeBlockLanguagePicker } from '../ui/CodeBlockLanguagePicker';
|
|
19
20
|
import { WrapIcon } from '../ui/icons/WrapIcon';
|
|
@@ -134,6 +135,7 @@ export var getToolbarConfig = function getToolbarConfig() {
|
|
|
134
135
|
options: languageSelectOptions,
|
|
135
136
|
filterOption: languageListFilter
|
|
136
137
|
};
|
|
138
|
+
var areAnyNewToolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar));
|
|
137
139
|
var languagePicker;
|
|
138
140
|
if (expValEquals('platform_editor_code_block_q4_lovability', 'isEnabled', true) && fg('platform_editor_code_block_add_line_number_button')) {
|
|
139
141
|
var autoDetectEntry = typeof localId === 'string' && fg('platform_editor_code_block_language_detection_flow') ? autoDetectState === null || autoDetectState === void 0 ? void 0 : autoDetectState.languageDetectionMap[localId] : undefined;
|
|
@@ -156,7 +158,8 @@ export var getToolbarConfig = function getToolbarConfig() {
|
|
|
156
158
|
editorView: view,
|
|
157
159
|
filterOption: languageListFilter,
|
|
158
160
|
formatMessage: formatMessage,
|
|
159
|
-
languagePickerOptions: languagePickerOptions
|
|
161
|
+
languagePickerOptions: languagePickerOptions,
|
|
162
|
+
triggerSpacing: !areAnyNewToolbarFlagsEnabled && fg('platform_editor_code_block_dogfooding_patch') ? 'compact' : 'default'
|
|
160
163
|
});
|
|
161
164
|
}
|
|
162
165
|
};
|
|
@@ -164,7 +167,6 @@ export var getToolbarConfig = function getToolbarConfig() {
|
|
|
164
167
|
var separator = {
|
|
165
168
|
type: 'separator'
|
|
166
169
|
};
|
|
167
|
-
var areAnyNewToolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar));
|
|
168
170
|
var copyToClipboardItems = !allowCopyToClipboard ? [] : [{
|
|
169
171
|
id: 'editor.codeBlock.copy',
|
|
170
172
|
type: 'button',
|
|
@@ -237,12 +239,12 @@ export var getToolbarConfig = function getToolbarConfig() {
|
|
|
237
239
|
};
|
|
238
240
|
copyAndDeleteButtonMenuItems = [separator].concat(copyToClipboardItems, [deleteButton]);
|
|
239
241
|
}
|
|
240
|
-
var codeBlockWrapButtonTitle =
|
|
242
|
+
var codeBlockWrapButtonTitle = expValEqualsNoExposure('platform_editor_code_block_q4_lovability', 'isEnabled', true) ? formatMessage(isWrapped ? codeBlockButtonMessages.unwrapCodeLabel : codeBlockButtonMessages.wrapCodeLabel) : formatMessage(codeBlockButtonMessages.wrapCode);
|
|
241
243
|
var codeBlockWrapButton = {
|
|
242
244
|
id: 'editor.codeBlock.wrap',
|
|
243
245
|
type: 'button',
|
|
244
246
|
// Toggling button now writes to ADF, hence it should be available in view mode
|
|
245
|
-
supportsViewMode: !
|
|
247
|
+
supportsViewMode: !expValEqualsNoExposure('platform_editor_code_block_q4_lovability', 'isEnabled', true),
|
|
246
248
|
icon: TextWrapIcon,
|
|
247
249
|
iconFallback: WrapIcon,
|
|
248
250
|
onClick: toggleWordWrapStateForCodeBlockNode(editorAnalyticsAPI),
|
|
@@ -12,7 +12,8 @@ export var CodeBlockLanguagePicker = function CodeBlockLanguagePicker(_ref) {
|
|
|
12
12
|
editorView = _ref.editorView,
|
|
13
13
|
filterOption = _ref.filterOption,
|
|
14
14
|
formatMessage = _ref.formatMessage,
|
|
15
|
-
languagePickerOptions = _ref.languagePickerOptions
|
|
15
|
+
languagePickerOptions = _ref.languagePickerOptions,
|
|
16
|
+
triggerSpacing = _ref.triggerSpacing;
|
|
16
17
|
var _useState = useState(function () {
|
|
17
18
|
return getRecentLanguages();
|
|
18
19
|
}),
|
|
@@ -26,11 +27,19 @@ export var CodeBlockLanguagePicker = function CodeBlockLanguagePicker(_ref) {
|
|
|
26
27
|
var _api$analytics;
|
|
27
28
|
var command = option.value === DETECT_LANGUAGE_VALUE && fg('platform_editor_code_block_language_detection_flow') ? detectLanguage() : changeLanguage(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions)(option.value, selectionSource);
|
|
28
29
|
var commandSucceeded = command(editorView.state, editorView.dispatch);
|
|
30
|
+
if (fg('platform_editor_code_block_dogfooding_patch')) {
|
|
31
|
+
requestAnimationFrame(function () {
|
|
32
|
+
// Let PopupSelect/FocusLock finish returning focus to the trigger, then restore the editor.
|
|
33
|
+
api === null || api === void 0 || api.core.actions.focus({
|
|
34
|
+
scrollIntoView: false
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
29
38
|
if (commandSucceeded && option.value !== DETECT_LANGUAGE_VALUE) {
|
|
30
39
|
saveRecentLanguage(option.value);
|
|
31
40
|
setRecentLanguageValues(getRecentLanguages());
|
|
32
41
|
}
|
|
33
|
-
}, [api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, editorView]);
|
|
42
|
+
}, [api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, api === null || api === void 0 ? void 0 : api.core.actions, editorView]);
|
|
34
43
|
return /*#__PURE__*/React.createElement(LanguagePicker, {
|
|
35
44
|
defaultValue: defaultValue,
|
|
36
45
|
filterOption: filterOption,
|
|
@@ -38,6 +47,7 @@ export var CodeBlockLanguagePicker = function CodeBlockLanguagePicker(_ref) {
|
|
|
38
47
|
languagePickerOptions: languagePickerOptions,
|
|
39
48
|
recentLanguageValues: recentLanguageValues,
|
|
40
49
|
onMenuOpen: refreshRecentLanguages,
|
|
41
|
-
onSelection: handleSelection
|
|
50
|
+
onSelection: handleSelection,
|
|
51
|
+
triggerSpacing: triggerSpacing
|
|
42
52
|
});
|
|
43
53
|
};
|
|
@@ -6,7 +6,8 @@ import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
|
6
6
|
import AngleBracketsIcon from '@atlaskit/icon/core/angle-brackets';
|
|
7
7
|
var NODE_NAME = 'codeBlock';
|
|
8
8
|
var CodeBlockMenuItem = function CodeBlockMenuItem(_ref) {
|
|
9
|
-
var api = _ref.api
|
|
9
|
+
var api = _ref.api,
|
|
10
|
+
isSuggested = _ref.isSuggested;
|
|
10
11
|
var _useIntl = useIntl(),
|
|
11
12
|
formatMessage = _useIntl.formatMessage;
|
|
12
13
|
var handleClick = function handleClick(event) {
|
|
@@ -17,6 +18,7 @@ var CodeBlockMenuItem = function CodeBlockMenuItem(_ref) {
|
|
|
17
18
|
var tr = _ref2.tr;
|
|
18
19
|
var command = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.commands.transformNode(tr.doc.type.schema.nodes.codeBlock, {
|
|
19
20
|
inputMethod: inputMethod,
|
|
21
|
+
isSuggested: isSuggested,
|
|
20
22
|
triggeredFrom: triggeredFrom,
|
|
21
23
|
targetTypeName: NODE_NAME
|
|
22
24
|
});
|
|
@@ -35,8 +37,11 @@ var CodeBlockMenuItem = function CodeBlockMenuItem(_ref) {
|
|
|
35
37
|
};
|
|
36
38
|
export var createCodeBlockMenuItem = function createCodeBlockMenuItem(api) {
|
|
37
39
|
return function () {
|
|
40
|
+
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
41
|
+
isSuggested = _ref3.isSuggested;
|
|
38
42
|
return /*#__PURE__*/React.createElement(CodeBlockMenuItem, {
|
|
39
|
-
api: api
|
|
43
|
+
api: api,
|
|
44
|
+
isSuggested: isSuggested
|
|
40
45
|
});
|
|
41
46
|
};
|
|
42
47
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* LanguagePicker.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
3
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
4
|
import "./LanguagePicker.compiled.css";
|
|
4
5
|
import { ax, ix } from "@compiled/react/runtime";
|
|
@@ -10,6 +11,7 @@ import Button from '@atlaskit/button/new';
|
|
|
10
11
|
import { codeBlockButtonMessages } from '@atlaskit/editor-common/messages';
|
|
11
12
|
import { akEditorLineHeight } from '@atlaskit/editor-shared-styles';
|
|
12
13
|
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
|
|
14
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
13
15
|
import { Box } from '@atlaskit/primitives/compiled';
|
|
14
16
|
import { PopupSelect, components } from '@atlaskit/select';
|
|
15
17
|
import { createGroupedLanguageOptions } from './language-picker-options';
|
|
@@ -51,6 +53,11 @@ var menuPopperProps = {
|
|
|
51
53
|
enabled: false
|
|
52
54
|
}]
|
|
53
55
|
};
|
|
56
|
+
var focusWithoutScrolling = function focusWithoutScrolling(element) {
|
|
57
|
+
element.focus({
|
|
58
|
+
preventScroll: true
|
|
59
|
+
});
|
|
60
|
+
};
|
|
54
61
|
var getRecentlyUsedLanguages = function getRecentlyUsedLanguages(recentLanguageValues, optionsByValue) {
|
|
55
62
|
var recentlyUsedLanguages = [];
|
|
56
63
|
var _iterator = _createForOfIteratorHelper(recentLanguageValues),
|
|
@@ -79,13 +86,19 @@ export var LanguagePicker = function LanguagePicker(_ref) {
|
|
|
79
86
|
_ref$recentLanguageVa = _ref.recentLanguageValues,
|
|
80
87
|
recentLanguageValues = _ref$recentLanguageVa === void 0 ? [] : _ref$recentLanguageVa,
|
|
81
88
|
onMenuOpen = _ref.onMenuOpen,
|
|
82
|
-
onSelection = _ref.onSelection
|
|
89
|
+
onSelection = _ref.onSelection,
|
|
90
|
+
_ref$triggerSpacing = _ref.triggerSpacing,
|
|
91
|
+
triggerSpacing = _ref$triggerSpacing === void 0 ? 'default' : _ref$triggerSpacing;
|
|
83
92
|
var label = (_defaultValue$label = defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.label) !== null && _defaultValue$label !== void 0 ? _defaultValue$label : formatMessage(codeBlockButtonMessages.selectLanguage);
|
|
84
93
|
var selectLanguageLabel = formatMessage(codeBlockButtonMessages.selectLanguage);
|
|
85
94
|
var _useState = useState(false),
|
|
86
95
|
_useState2 = _slicedToArray(_useState, 2),
|
|
87
96
|
hasSearchQuery = _useState2[0],
|
|
88
97
|
setHasSearchQuery = _useState2[1];
|
|
98
|
+
var _useState3 = useState(),
|
|
99
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
100
|
+
lockedPopperPlacement = _useState4[0],
|
|
101
|
+
setLockedPopperPlacement = _useState4[1];
|
|
89
102
|
var inputValueRef = useRef('');
|
|
90
103
|
var optionsByValue = useMemo(function () {
|
|
91
104
|
return new Map(languagePickerOptions.map(function (option) {
|
|
@@ -107,6 +120,29 @@ export var LanguagePicker = function LanguagePicker(_ref) {
|
|
|
107
120
|
return group.options;
|
|
108
121
|
});
|
|
109
122
|
}, [options]);
|
|
123
|
+
var stableMenuPopperProps = useMemo(function () {
|
|
124
|
+
return {
|
|
125
|
+
// Allow Popper to choose top on the first open when bottom has no room, then lock the
|
|
126
|
+
// chosen placement so later hover/search renders do not move the open picker.
|
|
127
|
+
placement: lockedPopperPlacement !== null && lockedPopperPlacement !== void 0 ? lockedPopperPlacement : 'bottom-start',
|
|
128
|
+
modifiers: [{
|
|
129
|
+
name: 'offset',
|
|
130
|
+
options: {
|
|
131
|
+
offset: [0, 8]
|
|
132
|
+
}
|
|
133
|
+
}, {
|
|
134
|
+
name: 'preventOverflow',
|
|
135
|
+
enabled: false
|
|
136
|
+
}].concat(_toConsumableArray(lockedPopperPlacement ? [{
|
|
137
|
+
name: 'flip',
|
|
138
|
+
enabled: false
|
|
139
|
+
}] : [])),
|
|
140
|
+
onFirstUpdate: function onFirstUpdate(_ref2) {
|
|
141
|
+
var placement = _ref2.placement;
|
|
142
|
+
setLockedPopperPlacement(placement);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}, [lockedPopperPlacement]);
|
|
110
146
|
var handleChange = useCallback(function (option) {
|
|
111
147
|
var _option$selectionSour;
|
|
112
148
|
if (!option) {
|
|
@@ -119,21 +155,45 @@ export var LanguagePicker = function LanguagePicker(_ref) {
|
|
|
119
155
|
var handleInputChange = useCallback(function (newInputValue, actionMeta) {
|
|
120
156
|
// React-select clears the input as part of selecting a value before onChange fires.
|
|
121
157
|
// Keep the last user-typed query so handleChange can report search selections correctly.
|
|
122
|
-
|
|
158
|
+
var isInputChange = !actionMeta || actionMeta.action === 'input-change';
|
|
159
|
+
if (isInputChange) {
|
|
123
160
|
inputValueRef.current = newInputValue;
|
|
124
161
|
}
|
|
125
|
-
|
|
126
|
-
|
|
162
|
+
if (isInputChange || !fg('platform_editor_code_block_dogfooding_patch')) {
|
|
163
|
+
setHasSearchQuery(newInputValue.trim().length > 0);
|
|
164
|
+
return newInputValue;
|
|
165
|
+
}
|
|
166
|
+
return inputValueRef.current;
|
|
167
|
+
}, []);
|
|
168
|
+
var handleMenuOpen = useCallback(function () {
|
|
169
|
+
if (fg('platform_editor_code_block_dogfooding_patch')) {
|
|
170
|
+
inputValueRef.current = '';
|
|
171
|
+
setHasSearchQuery(false);
|
|
172
|
+
setLockedPopperPlacement(undefined);
|
|
173
|
+
}
|
|
174
|
+
onMenuOpen === null || onMenuOpen === void 0 || onMenuOpen();
|
|
175
|
+
}, [onMenuOpen]);
|
|
176
|
+
var handleTriggerMouseDown = useCallback(function (event) {
|
|
177
|
+
if (fg('platform_editor_code_block_dogfooding_patch')) {
|
|
178
|
+
// PopupSelect's FocusLock returns focus to the element that was focused before the
|
|
179
|
+
// picker opened. If that is the editor/code block, closing the picker can scroll the
|
|
180
|
+
// whole code block into view. Focus the trigger first without scrolling so FocusLock
|
|
181
|
+
// returns to the trigger; see CodeBlockLanguagePicker's handleSelection for restoring
|
|
182
|
+
// editor focus.
|
|
183
|
+
focusWithoutScrolling(event.currentTarget);
|
|
184
|
+
}
|
|
127
185
|
}, []);
|
|
128
|
-
var renderTarget = useCallback(function (
|
|
129
|
-
var isOpen =
|
|
130
|
-
ref =
|
|
131
|
-
onKeyDown =
|
|
132
|
-
ariaControls =
|
|
186
|
+
var renderTarget = useCallback(function (_ref3) {
|
|
187
|
+
var isOpen = _ref3.isOpen,
|
|
188
|
+
ref = _ref3.ref,
|
|
189
|
+
onKeyDown = _ref3.onKeyDown,
|
|
190
|
+
ariaControls = _ref3['aria-controls'];
|
|
133
191
|
return /*#__PURE__*/React.createElement("div", {
|
|
134
192
|
className: ax([styles.trigger])
|
|
135
193
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
194
|
+
spacing: triggerSpacing,
|
|
136
195
|
shouldFitContainer: true,
|
|
196
|
+
onMouseDown: handleTriggerMouseDown,
|
|
137
197
|
onKeyDown: onKeyDown,
|
|
138
198
|
ref: ref,
|
|
139
199
|
iconAfter: ChevronDownIcon,
|
|
@@ -142,7 +202,7 @@ export var LanguagePicker = function LanguagePicker(_ref) {
|
|
|
142
202
|
"aria-controls": ariaControls,
|
|
143
203
|
testId: "code-block-language-picker-trigger"
|
|
144
204
|
}, label));
|
|
145
|
-
}, [label]);
|
|
205
|
+
}, [label, triggerSpacing, handleTriggerMouseDown]);
|
|
146
206
|
return /*#__PURE__*/React.createElement(PopupSelect, {
|
|
147
207
|
components: popupSelectComponents,
|
|
148
208
|
filterOption: filterOption,
|
|
@@ -152,9 +212,9 @@ export var LanguagePicker = function LanguagePicker(_ref) {
|
|
|
152
212
|
menuPlacement: "auto",
|
|
153
213
|
onChange: handleChange,
|
|
154
214
|
onInputChange: handleInputChange,
|
|
155
|
-
onMenuOpen:
|
|
215
|
+
onMenuOpen: handleMenuOpen,
|
|
156
216
|
options: hasSearchQuery ? searchOptions : options,
|
|
157
|
-
popperProps: menuPopperProps,
|
|
217
|
+
popperProps: fg('platform_editor_code_block_dogfooding_patch') ? stableMenuPopperProps : menuPopperProps,
|
|
158
218
|
searchThreshold: -1,
|
|
159
219
|
target: renderTarget,
|
|
160
220
|
testId: "code-block-language-picker",
|
|
@@ -3,6 +3,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
3
3
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
4
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
5
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
6
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
7
|
import { ACTIONS } from '../pm-plugins/actions';
|
|
7
8
|
import { autoDetectPluginKey } from '../pm-plugins/auto-detect-state';
|
|
8
9
|
import { createAutoDetectEntry } from './auto-detect-state';
|
|
@@ -36,6 +37,7 @@ var runPendingDetection = function runPendingDetection(view, localId, api) {
|
|
|
36
37
|
}
|
|
37
38
|
var detectedLanguage = detectLanguage(found.node.textContent);
|
|
38
39
|
var detectionResult = detectedLanguage ? 'detected' : 'noneDetected';
|
|
40
|
+
var detectionPhase = entry.detectionResult ? 'redetection' : 'initial';
|
|
39
41
|
// Keep a previous auto-detected language when the latest snippet is too weak to classify.
|
|
40
42
|
var shouldPreserveAutoDetectedLanguage = !detectedLanguage && Boolean(entry.autoDetectedLanguage) && found.node.attrs.language === entry.autoDetectedLanguage;
|
|
41
43
|
var nextEntry = _objectSpread(_objectSpread({}, createAutoDetectEntry(found.node, found.pos, false, entry)), {}, {
|
|
@@ -45,10 +47,12 @@ var runPendingDetection = function runPendingDetection(view, localId, api) {
|
|
|
45
47
|
|
|
46
48
|
// If there is no confident detection, record the result without clearing user-visible language.
|
|
47
49
|
var shouldOnlyUpdateDetectionState = !detectedLanguage && (!found.node.attrs.language || shouldPreserveAutoDetectedLanguage);
|
|
50
|
+
var hasDetectedLanguageChange = Boolean(detectedLanguage) && found.node.attrs.language !== detectedLanguage;
|
|
51
|
+
var shouldClearStaleLanguage = !detectedLanguage && Boolean(found.node.attrs.language) && !shouldPreserveAutoDetectedLanguage;
|
|
52
|
+
var shouldUpdateNodeLanguage = fg('platform_editor_code_block_dogfooding_patch') ? hasDetectedLanguageChange || shouldClearStaleLanguage : !shouldOnlyUpdateDetectionState;
|
|
48
53
|
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref) {
|
|
49
|
-
var _api$analytics;
|
|
50
54
|
var tr = _ref.tr;
|
|
51
|
-
if (
|
|
55
|
+
if (shouldUpdateNodeLanguage) {
|
|
52
56
|
tr.setNodeMarkup(found.pos, undefined, _objectSpread(_objectSpread({}, found.node.attrs), {}, {
|
|
53
57
|
language: detectedLanguage
|
|
54
58
|
}), found.node.marks);
|
|
@@ -60,15 +64,21 @@ var runPendingDetection = function runPendingDetection(view, localId, api) {
|
|
|
60
64
|
entry: nextEntry
|
|
61
65
|
}
|
|
62
66
|
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
// When platform_editor_code_block_dogfooding_patch is cleaned up, merge this with the previous shouldUpdateNodeLanguage check.
|
|
68
|
+
if (!fg('platform_editor_code_block_dogfooding_patch') || shouldUpdateNodeLanguage) {
|
|
69
|
+
var _api$analytics;
|
|
70
|
+
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.attachAnalyticsEvent({
|
|
71
|
+
action: ACTION.LANGUAGE_AUTO_DETECTED,
|
|
72
|
+
actionSubject: ACTION_SUBJECT.CODE_BLOCK,
|
|
73
|
+
attributes: _objectSpread({
|
|
74
|
+
language: detectedLanguage !== null && detectedLanguage !== void 0 ? detectedLanguage : 'none',
|
|
75
|
+
detectionResult: detectionResult
|
|
76
|
+
}, fg('platform_editor_code_block_dogfooding_patch') ? {
|
|
77
|
+
detectionPhase: detectionPhase
|
|
78
|
+
} : {}),
|
|
79
|
+
eventType: EVENT_TYPE.TRACK
|
|
80
|
+
})(tr);
|
|
81
|
+
}
|
|
72
82
|
// Language detection runs in the background and should not move the viewport.
|
|
73
83
|
return tr.setMeta('scrollIntoView', false);
|
|
74
84
|
});
|