import { EditorExtensions } from "editor-enhancements" ; import { Plugin , MarkdownView , Editor } from "obsidian" ; import { AutoLinkTitleSettings , DEFAULT_SETTINGS } from './settings' ; import { CheckIf } from "checkif" ; import getPageTitle from "scraper" ; interface PasteFunction { ( this , ev ) : void ; } export default class AutoLinkTitle extends Plugin { settings : AutoLinkTitleSettings ; pasteFunction : PasteFunction ; async onload ( ) { console . log ( "loading obsidian-auto-link-title" ) ; await this . loadSettings ( ) ; this . pasteFunction = this . pasteUrlWithTitle . bind ( this ) ; this . app . workspace . containerEl . addEventListener ( "paste" , this . pasteFunction , true ) ; this . addCommand ( { id : "enhance-url-with-title" , name : "Enhance existing URL with link and title" , callback : ( ) => this . addTitleToLink ( ) , hotkeys : [ { modifiers : [ "Mod" , "Shift" ] , key : "e" , } , ] , } ) ; } addTitleToLink ( ) { if ( ! navigator . onLine ) return ; let editor = this . getEditor ( ) ; if ( editor == null ) return ; let selectedText = ( EditorExtensions . getSelectedText ( editor ) || "" ) . trim ( ) ; if ( CheckIf . isUrl ( selectedText ) ) { this . convertUrlToTitledLink ( editor , selectedText ) ; } else if ( CheckIf . isLinkedUrl ( selectedText ) ) { var link = this . getUrlFromLink ( selectedText ) ; this . convertUrlToTitledLink ( editor , link ) ; } } pasteUrlWithTitle ( clipboard ) { if ( ! navigator . onLine ) return ; let editor = this . getEditor ( ) ; let clipboardText = clipboard . clipboardData . getData ( "text/plain" ) ; if ( clipboardText == null || clipboardText == "" ) return ; if ( ! CheckIf . isUrl ( clipboardText ) || CheckIf . isImage ( clipboardText ) ) { return ; } clipboard . stopPropagation ( ) ; clipboard . preventDefault ( ) ; if ( CheckIf . isMarkdownLinkAlready ( editor ) || CheckIf . isAfterQuote ( editor ) ) { editor . replaceSelection ( clipboardText ) ; return ; } this . convertUrlToTitledLink ( editor , clipboardText ) ; return ; } convertUrlToTitledLink ( editor , text ) { let pasteId = `Fetching Title#${ this . createBlockHash ( ) }` ; editor . replaceSelection ( `[${ pasteId }](${ text })` ) ; this . fetchUrlTitle ( text ) . then ( ( title ) => { let text = editor . getValue ( ) ; let start = text . indexOf ( pasteId ) ; let end = start + pasteId . length ; let startPos = EditorExtensions . getEditorPositionFromIndex ( text , start ) ; let endPos = EditorExtensions . getEditorPositionFromIndex ( text , end ) ; editor . replaceRange ( title , startPos , endPos ) ; } ) ; } fetchUrlTitle ( text ) { return getPageTitle ( text ) . then ( title => { if ( title == null || title == "" ) { return "Title Unknown" ; } return title . trim ( ) ; } ) . catch ( ( error ) => { return "Site Unreachable" ; } ) ; } private getEditor ( ) { let activeLeaf = this . app . workspace . getActiveViewOfType ( MarkdownView ) ; if ( activeLeaf == null ) return ; return activeLeaf . editor ; } public getUrlFromLink ( text ) { let urlRegex = new RegExp ( DEFAULT_SETTINGS . linkRegex ) ; return urlRegex . exec ( text ) [ 2 ] ; } private createBlockHash ( ) { let result = "" ; var characters = "abcdefghijklmnopqrstuvwxyz0123456789" ; var charactersLength = characters . length ; for ( var i = 0 ; i < 4 ; i ++ ) { result += characters . charAt ( Math . floor ( Math . random ( ) * charactersLength ) ) ; } return result ; } onunload ( ) { console . log ( "unloading obsidian-auto-link-title" ) ; this . app . workspace . containerEl . removeEventListener ( "paste" , this . pasteFunction , true ) ; } async loadSettings ( ) { this . settings = Object . assign ( { } , DEFAULT_SETTINGS , await this . loadData ( ) ) ; } async saveSettings ( ) { await this . saveData ( this . settings ) ; } }