You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-07-13 00:10:37 +02:00
Mobile: Note editor: Hash links: Move cursor to header or anchor associated with link target (#12129)
This commit is contained in:
@ -49,6 +49,7 @@ describe('NoteEditor', () => {
|
|||||||
themeId={Setting.THEME_ARITIM_DARK}
|
themeId={Setting.THEME_ARITIM_DARK}
|
||||||
initialText='Testing...'
|
initialText='Testing...'
|
||||||
noteId=''
|
noteId=''
|
||||||
|
noteHash=''
|
||||||
style={{}}
|
style={{}}
|
||||||
toolbarEnabled={true}
|
toolbarEnabled={true}
|
||||||
readOnly={false}
|
readOnly={false}
|
||||||
|
@ -42,6 +42,7 @@ interface Props {
|
|||||||
themeId: number;
|
themeId: number;
|
||||||
initialText: string;
|
initialText: string;
|
||||||
noteId: string;
|
noteId: string;
|
||||||
|
noteHash: string;
|
||||||
initialSelection?: SelectionRange;
|
initialSelection?: SelectionRange;
|
||||||
style: ViewStyle;
|
style: ViewStyle;
|
||||||
toolbarEnabled: boolean;
|
toolbarEnabled: boolean;
|
||||||
@ -332,6 +333,9 @@ function NoteEditor(props: Props, ref: any) {
|
|||||||
cm.select(${props.initialSelection.start}, ${props.initialSelection.end});
|
cm.select(${props.initialSelection.start}, ${props.initialSelection.end});
|
||||||
cm.execCommand('scrollSelectionIntoView');
|
cm.execCommand('scrollSelectionIntoView');
|
||||||
` : '';
|
` : '';
|
||||||
|
const jumpToHashJs = props.noteHash ? `
|
||||||
|
cm.jumpToHash(${JSON.stringify(props.noteHash)});
|
||||||
|
` : '';
|
||||||
|
|
||||||
const editorSettings: EditorSettings = useMemo(() => ({
|
const editorSettings: EditorSettings = useMemo(() => ({
|
||||||
themeId: props.themeId,
|
themeId: props.themeId,
|
||||||
@ -391,6 +395,9 @@ function NoteEditor(props: Props, ref: any) {
|
|||||||
settings
|
settings
|
||||||
);
|
);
|
||||||
|
|
||||||
|
${jumpToHashJs}
|
||||||
|
// Set the initial selection after jumping to the header -- the initial selection,
|
||||||
|
// if specified, should take precedence.
|
||||||
${setInitialSelectionJS}
|
${setInitialSelectionJS}
|
||||||
|
|
||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
@ -425,6 +432,20 @@ function NoteEditor(props: Props, ref: any) {
|
|||||||
}
|
}
|
||||||
}, [css]);
|
}, [css]);
|
||||||
|
|
||||||
|
// Scroll to the new hash, if it changes.
|
||||||
|
const isFirstScrollRef = useRef(true);
|
||||||
|
useEffect(() => {
|
||||||
|
// The first "jump to header" is handled during editor setup and shouldn't
|
||||||
|
// be handled a second time:
|
||||||
|
if (isFirstScrollRef.current) {
|
||||||
|
isFirstScrollRef.current = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (jumpToHashJs && webviewRef.current) {
|
||||||
|
webviewRef.current.injectJS(jumpToHashJs);
|
||||||
|
}
|
||||||
|
}, [jumpToHashJs]);
|
||||||
|
|
||||||
const html = useHtml(css);
|
const html = useHtml(css);
|
||||||
const [selectionState, setSelectionState] = useState<SelectionFormatting>(defaultSelectionFormatting);
|
const [selectionState, setSelectionState] = useState<SelectionFormatting>(defaultSelectionFormatting);
|
||||||
const [linkDialogVisible, setLinkDialogVisible] = useState(false);
|
const [linkDialogVisible, setLinkDialogVisible] = useState(false);
|
||||||
|
@ -1585,6 +1585,7 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
|||||||
toolbarEnabled={this.props.toolbarEnabled}
|
toolbarEnabled={this.props.toolbarEnabled}
|
||||||
themeId={this.props.themeId}
|
themeId={this.props.themeId}
|
||||||
noteId={this.props.noteId}
|
noteId={this.props.noteId}
|
||||||
|
noteHash={this.props.noteHash}
|
||||||
initialText={note.body}
|
initialText={note.body}
|
||||||
initialSelection={this.selection}
|
initialSelection={this.selection}
|
||||||
onChange={this.onMarkdownEditorTextChange}
|
onChange={this.onMarkdownEditorTextChange}
|
||||||
|
Reference in New Issue
Block a user