2022-03-08 15:55:41 +01:00
$ ( document ) . ready ( function ( ) {
2024-04-04 14:37:20 +02:00
if ( ! ProcessWire . config . ProcessPageEditLink ) return ;
var cfg = ProcessWire . config . ProcessPageEditLink ;
2022-03-08 15:55:41 +01:00
var options = {
2024-04-04 14:37:20 +02:00
selectStartLabel : cfg . selectStartLabel ,
selectSelectLabel : cfg . selectStartLabel ,
langID : cfg . langID
2022-03-08 15:55:41 +01:00
// openPageIDs: config.ProcessPageEditLink.openPageIDs
2024-04-04 14:37:20 +02:00
} ;
2022-03-08 15:55:41 +01:00
var options2 = {
selectStartLabel : options . selectStartLabel ,
selectSelectLabel : options . selectStartLabel ,
langID : options . langID ,
2024-04-04 14:37:20 +02:00
rootPageID : cfg . pageID
} ;
2022-03-08 15:55:41 +01:00
var selectedPageData = {
id : 0 ,
title : '' ,
url : ''
} ;
var $fileSelect = $ ( "#link_page_file" ) ;
var $anchorSelect = $ ( "#link_page_anchor" ) ;
var $linkPageURL = $ ( "#link_page_url_input" ) ;
var $linkText = $ ( "#link_text" ) ;
$linkPageURL . val ( $ ( "#link_page_url" ) . val ( ) ) ; // copy from hidden
function populateFileSelect ( selectedPageData ) {
// populate the files field
var $wrap = $ ( "#wrap_link_page_file" ) ;
$ . getJSON ( "./files?id=" + selectedPageData . id , function ( data ) {
$fileSelect . empty ( ) ;
$fileSelect . append ( "<option></option>" ) ;
$ . each ( data , function ( key , val ) {
var $option = $ ( "<option value='" + key + "'>" + val + "</option>" ) ;
$fileSelect . append ( $option ) ;
} ) ;
$wrap . find ( "p.notes strong" ) . text ( selectedPageData . url ) ;
if ( $fileSelect . is ( ":visible" ) ) {
$wrap . children ( ) . effect ( 'highlight' , { } , 500 ) ;
$fileSelect . effect ( 'bounce' , { } , 50 ) ;
}
} ) ;
}
function absoluteToRelativePath ( path ) {
2024-04-04 14:37:20 +02:00
if ( cfg . urlType == 0 ) return path ;
2022-03-08 15:55:41 +01:00
function slashesToRelative ( url ) {
url = url . replace ( /\//g , '../' ) ;
url = url . replace ( /[^.\/]/g , '' ) ;
return url ;
}
var url ;
2024-04-04 14:37:20 +02:00
if ( path === cfg . pageUrl ) {
2022-03-08 15:55:41 +01:00
// account for the link to self
path = './' ;
2024-04-04 14:37:20 +02:00
if ( ! cfg . slashUrls ) path += cfg . pageName ;
2022-03-08 15:55:41 +01:00
2024-04-04 14:37:20 +02:00
} else if ( path . indexOf ( cfg . pageUrl ) === 0 ) {
2022-03-08 15:55:41 +01:00
// linking to child of current page
2024-04-04 14:37:20 +02:00
path = path . substring ( cfg . pageUrl . length ) ;
if ( ! cfg . slashUrls ) path = cfg . pageName + path ;
2022-03-08 15:55:41 +01:00
2024-04-04 14:37:20 +02:00
} else if ( cfg . pageUrl . indexOf ( path ) === 0 ) {
2022-03-08 15:55:41 +01:00
// linking to a parent of the current page
2024-04-04 14:37:20 +02:00
url = cfg . pageUrl . substring ( path . length ) ;
2022-03-08 15:55:41 +01:00
if ( url . indexOf ( '/' ) != - 1 ) {
url = slashesToRelative ( url ) ;
} else {
url = './' ;
}
path = url ;
2024-04-04 14:37:20 +02:00
} else if ( path . indexOf ( cfg . rootParentUrl ) === 0 ) {
2022-03-08 15:55:41 +01:00
// linking to a sibling or other page in same branch (but not a child)
2024-04-04 14:37:20 +02:00
url = path . substring ( cfg . rootParentUrl . length ) ;
2022-03-08 15:55:41 +01:00
var url2 = url ;
url = slashesToRelative ( url ) + url2 ;
path = url ;
2024-04-04 14:37:20 +02:00
} else if ( cfg . urlType == 2 ) { // 2=relative for all
2022-03-08 15:55:41 +01:00
// page in a different tree than current
// traverse back to root
2024-04-04 14:37:20 +02:00
url = cfg . pageUrl . substring ( ProcessWire . config . urls . root . length ) ;
2022-03-08 15:55:41 +01:00
url = slashesToRelative ( url ) ;
path = path . substring ( ProcessWire . config . urls . root . length ) ;
path = url + path ;
}
return path ;
}
function pageSelected ( event , data ) {
if ( data . url && data . url . length ) {
selectedPageData = data ;
selectedPageData . url = ProcessWire . config . urls . root + data . url . substring ( 1 ) ;
selectedPageData . url = absoluteToRelativePath ( selectedPageData . url ) ;
2024-04-04 14:37:20 +02:00
$linkPageURL . val ( selectedPageData . url ) . trigger ( 'change' ) ;
2022-03-08 15:55:41 +01:00
populateFileSelect ( selectedPageData ) ; // was: if($fileSelect.is(":visible")) { ... }
}
2024-04-04 14:37:20 +02:00
$ ( this ) . parents ( ".InputfieldInteger" ) . children ( ".InputfieldHeader" ) . trigger ( 'click' ) // to close the field
2022-03-08 15:55:41 +01:00
. parent ( ) . find ( '.PageListSelectHeader' ) . removeClass ( 'hidden' ) . show ( ) ; // to open the pagelist select header so it can be re-used if the field is opened again
}
2024-04-04 14:37:20 +02:00
$ ( "#link_page_id" ) . ProcessPageList ( options ) . hide ( ) . on ( 'pageSelected' , pageSelected ) ;
$ ( "#child_page_id" ) . ProcessPageList ( options2 ) . hide ( ) . on ( 'pageSelected' , pageSelected ) ;
2022-03-08 15:55:41 +01:00
2024-04-04 14:37:20 +02:00
$fileSelect . on ( 'change' , function ( ) {
2022-03-08 15:55:41 +01:00
var $t = $ ( this ) ;
var src = $t . val ( ) ;
2024-04-04 14:37:20 +02:00
if ( src . length ) $linkPageURL . val ( src ) . trigger ( 'change' ) ;
2022-03-08 15:55:41 +01:00
} ) ;
if ( $anchorSelect . length ) {
var anchorPreviousValue = $anchorSelect . val ( ) ;
2024-04-04 14:37:20 +02:00
$anchorSelect . on ( 'change' , function ( ) {
2022-03-08 15:55:41 +01:00
var val = $ ( this ) . val ( ) ;
if ( val . length ) {
// populated anchor value
$linkPageURL . val ( val ) ;
anchorPreviousValue = val ;
} else {
// empty value
// make URL field blank only if present value is the same as a previously selected anchor value
if ( $linkPageURL . val ( ) == anchorPreviousValue ) $linkPageURL . val ( '' ) ;
}
2024-04-04 14:37:20 +02:00
$linkPageURL . trigger ( 'change' ) ;
2022-03-08 15:55:41 +01:00
} ) ;
// de-select anchor when URL is changed to something other than an ahcor
2024-04-04 14:37:20 +02:00
// $linkPageURL.on('change', function() {
2022-03-08 15:55:41 +01:00
// });
}
// auto-insert scheme/protocol when not present and domain is detected
function updateLinkPreview ( ) {
if ( ! $linkPageURL . val ( ) . length ) {
$ ( "#link_markup" ) . text ( '' ) ;
return ;
}
var $link = $ ( "<a />" ) ;
$link . attr ( 'href' , $linkPageURL . val ( ) ) ;
var $linkTitle = $ ( "#link_title" ) ;
if ( $linkTitle . length && $linkTitle . val ( ) . length ) {
var val = $ ( "<div />" ) . text ( $linkTitle . val ( ) ) . html ( ) ;
$link . attr ( 'title' , val ) ;
}
2024-04-04 14:37:20 +02:00
if ( cfg . noLinkTextEdit ) {
// link text editing disabled
} else if ( $linkText . length && $linkText . val ( ) . length ) {
2022-03-08 15:55:41 +01:00
$link . text ( $linkText . val ( ) ) ;
}
var $linkRel = $ ( "#link_rel" ) ;
2024-04-04 14:37:20 +02:00
if ( $linkRel . length && $linkRel . val ( ) && $linkRel . val ( ) . length ) {
2022-03-08 15:55:41 +01:00
$link . attr ( 'rel' , $linkRel . val ( ) ) ;
}
var $linkTarget = $ ( "#link_target" ) ;
if ( $linkTarget . length && $linkTarget . val ( ) . length ) {
$link . attr ( 'target' , $linkTarget . val ( ) ) ;
}
var $linkClass = $ ( "#wrap_link_class" ) . find ( 'input:checked' ) ;
if ( $linkClass . length ) {
$linkClass . each ( function ( ) {
$link . addClass ( $ ( this ) . val ( ) ) ;
} ) ;
}
$ ( "#link_markup" ) . text ( $link [ 0 ] . outerHTML ) ;
}
function urlKeydown ( ) {
var $this = $linkPageURL ;
2024-04-04 14:37:20 +02:00
var val = ProcessWire . trim ( $this . val ( ) ) ;
2022-03-08 15:55:41 +01:00
var dotpos = val . indexOf ( '.' ) ;
var slashespos = val . indexOf ( '//' ) ;
var hasScheme = slashespos > - 1 && slashespos < dotpos ;
var slashpos = ( slashespos > - 1 ? val . indexOf ( '/' , slashespos + 2 ) : val . indexOf ( '/' ) ) ;
var httpHost ;
var n ;
if ( dotpos > - 1 && val . indexOf ( '..' ) == - 1 && val . indexOf ( './' ) == - 1 && (
( slashpos > dotpos && ! hasScheme ) ||
( slashpos == - 1 && dotpos > 1 && val . match ( /^[a-z][-a-z.0-9]+\.[a-z]{2,}($|\/)/i ) )
) ) {
// no scheme present and matched: [www.]domain.com or [www.]domain.com/path/...
var domain = val . substring ( 0 , ( slashpos > 0 ? slashpos : val . length ) ) ;
hasScheme = true ;
// avoid adding scheme if we already added it before and user removed it
if ( $this . attr ( 'data-ignore' ) == domain ) {
// do nothing
} else {
$this . val ( 'http://' + val ) ;
$this . closest ( '.InputfieldContent' ) . find ( '.notes' ) . text ( 'http://' + val ) ;
$this . attr ( 'data-ignore' , domain ) ;
}
} else if ( dotpos > 0 &&
val . indexOf ( '@' ) > 0 &&
val . indexOf ( ':' ) == - 1 &&
val . match ( /^[^@]+@[-.a-z0-9]{2,}\.[a-z]{2,}$/i ) ) {
// email address
$this . val ( 'mailto:' + val ) ;
$this . addClass ( 'email' ) ;
} else if ( val . indexOf ( '@' ) == - 1 && $this . hasClass ( 'email' ) ) {
$this . removeClass ( 'email' ) ;
}
if ( val . substring ( 0 , 1 ) == '#' ) {
$this . addClass ( 'anchor' ) ;
} else if ( $this . hasClass ( 'anchor' ) ) {
$this . removeClass ( 'anchor' ) ;
}
if ( hasScheme ) {
2024-04-04 14:37:20 +02:00
if ( slashpos == - 1 ) slashpos = val . length ;
2022-03-08 15:55:41 +01:00
httpHost = ( slashespos > - 1 ? val . substring ( slashespos + 2 , slashpos ) : val . substring ( 0 , slashpos ) ) ;
$this . attr ( 'data-httphost' , httpHost ) ;
} else {
$this . removeAttr ( 'data-httphost' ) ;
}
// console.log('httpHost=' + $this.attr('data-httphost'));
function icon ( ) {
return $this . closest ( '.Inputfield' ) . children ( '.InputfieldHeader' ) . children ( 'i' ) . eq ( 0 ) ;
}
var external = false ;
httpHost = $this . attr ( 'data-httphost' ) ;
if ( httpHost && httpHost . length ) {
external = true ;
for ( n = 0 ; n < ProcessWire . config . httpHosts ; n ++ ) {
if ( ProcessWire . config . httpHosts [ n ] == httpHost ) {
external = false ;
break ;
}
}
}
var primaryIcon = 'fa-external-link-square' ;
var extLinkIcon = 'fa-external-link' ;
var emailIcon = 'fa-envelope-o' ;
var anchorIcon = 'fa-flag-o' ;
2024-04-04 14:37:20 +02:00
var allIcons = primaryIcon + ' ' + extLinkIcon + ' ' + emailIcon + ' ' + anchorIcon ;
var extLinkClass = cfg . extLinkClass ;
var extLinkClassAll = extLinkClass . replace ( ' ' , '_' ) ;
var extLinkClasses = extLinkClass . indexOf ( ' ' ) > - 1 ? extLinkClass . split ( ' ' ) : [ extLinkClass ] ;
var extLinkRel = cfg . extLinkRel ;
var extLinkTarget = cfg . extLinkTarget ;
2022-03-08 15:55:41 +01:00
if ( external ) {
2024-04-04 14:37:20 +02:00
if ( ! $this . hasClass ( 'external-link' ) ) {
2022-03-08 15:55:41 +01:00
icon ( ) . removeClass ( allIcons ) . addClass ( extLinkIcon ) ;
$this . addClass ( 'external-link' ) ;
2024-04-04 14:37:20 +02:00
if ( extLinkTarget . length > 0 ) $ ( "#link_target" ) . val ( extLinkTarget ) ;
if ( extLinkRel . length > 0 ) $ ( "#link_rel" ) . val ( extLinkRel ) ;
if ( extLinkClasses . length > 0 ) {
if ( extLinkClasses . length > 1 ) {
$ ( "#link_class_" + extLinkClassAll ) . prop ( 'checked' , true ) ; // all classes in 1 option
}
for ( n = 0 ; n < extLinkClasses . length ; n ++ ) {
$ ( "#link_class_" + extLinkClasses [ n ] ) . prop ( 'checked' , true ) ;
2022-03-08 15:55:41 +01:00
}
}
}
} else {
2024-04-04 14:37:20 +02:00
if ( $this . hasClass ( 'external-link' ) ) {
// was previously an external link but no longer is
$this . removeClass ( 'external-link' ) ;
if ( extLinkRel . length ) $ ( '#link_rel' ) . val ( '' ) ;
if ( extLinkTarget . length ) $ ( '#link_target' ) . val ( '' ) ;
$ ( "#link_class_" + extLinkClassAll ) . prop ( 'checked' , false ) ; // all classes in 1 option
for ( n = 0 ; n < extLinkClasses . length ; n ++ ) {
$ ( "#link_class_" + extLinkClasses [ n ] ) . prop ( 'checked' , false ) ;
}
}
var $icon = icon ( ) ;
2022-03-08 15:55:41 +01:00
if ( $this . hasClass ( 'email' ) ) {
2024-04-04 14:37:20 +02:00
if ( ! $icon . hasClass ( emailIcon ) ) $icon . removeClass ( allIcons ) . addClass ( emailIcon ) ;
2022-03-08 15:55:41 +01:00
} else if ( $this . hasClass ( 'anchor' ) ) {
2024-04-04 14:37:20 +02:00
if ( ! $icon . hasClass ( anchorIcon ) ) $icon . removeClass ( allIcons ) . addClass ( anchorIcon ) ;
2022-03-08 15:55:41 +01:00
} else if ( ! $this . hasClass ( primaryIcon ) ) {
2024-04-04 14:37:20 +02:00
$icon . removeClass ( allIcons ) . addClass ( primaryIcon ) ;
2022-03-08 15:55:41 +01:00
}
}
updateLinkPreview ( ) ;
}
var urlKeydownTimer = null ;
2024-04-04 14:37:20 +02:00
$linkPageURL . trigger ( 'focus' ) . on ( 'keydown' , function ( event ) {
2022-03-08 15:55:41 +01:00
if ( urlKeydownTimer ) clearTimeout ( urlKeydownTimer ) ;
urlKeydownTimer = setTimeout ( function ( ) { urlKeydown ( ) ; } , 500 ) ;
} ) ;
2024-04-04 14:37:20 +02:00
$linkPageURL . on ( 'change' , function ( ) {
2022-03-08 15:55:41 +01:00
var val = $ ( this ) . val ( ) ;
if ( $anchorSelect . length ) {
if ( val . substring ( 0 , 1 ) == '#' ) {
var found = '' ;
2024-04-04 14:37:20 +02:00
$anchorSelect . children ( 'option' ) . each ( function ( ) {
if ( $ ( this ) . attr ( 'value' ) == val ) found = val ;
2022-03-08 15:55:41 +01:00
} ) ;
$anchorSelect . val ( found ) ;
} else if ( $anchorSelect . val ( ) . length ) {
$anchorSelect . val ( '' ) ;
}
}
$ ( "#link_page_url" ) . val ( val ) ; // legacy
urlKeydown ( ) ;
} ) ;
setTimeout ( function ( ) {
2024-04-04 14:37:20 +02:00
$linkPageURL . trigger ( 'change' ) ;
$linkText . trigger ( 'change' ) ;
2022-03-08 15:55:41 +01:00
} , 250 ) ;
2024-04-04 14:37:20 +02:00
$ ( ":input" ) . on ( 'change' , updateLinkPreview ) ;
$ ( "#link_title" ) . on ( 'keydown' , function ( event ) { updateLinkPreview ( ) ; } ) ;
$linkText . on ( 'keyup' , function ( event ) { updateLinkPreview ( ) ; } ) ;
2022-03-08 15:55:41 +01:00
// when header is clicked, open up the pageList right away
2024-04-04 14:37:20 +02:00
$ ( ".InputfieldInteger .InputfieldHeader" ) . on ( 'click' , function ( ) {
2022-03-08 15:55:41 +01:00
var $t = $ ( this ) ;
var $toggle = $t . parent ( ) . find ( ".PageListSelectActionToggle" ) ;
var $pageSelectHeader = $toggle . parents ( '.PageListSelectHeader' ) ;
2024-04-04 14:37:20 +02:00
if ( $pageSelectHeader . is ( '.hidden' ) ) {
2022-03-08 15:55:41 +01:00
// we previously hid the pageSelectHeader since it's not necessary in this context
// so, we can assume the field is already open, and is now being closed
return true ;
}
// hide the pageSelectHeader since it's extra visual baggage here we don't need
$pageSelectHeader . addClass ( 'hidden' ) . hide ( ) ;
// automatically open the PageListSelect
2024-04-04 14:37:20 +02:00
setTimeout ( function ( ) { $toggle . trigger ( 'click' ) ; } , 250 ) ;
2022-03-08 15:55:41 +01:00
return true ;
} ) ;
2024-04-04 14:37:20 +02:00
var $form = $ ( '#ProcessPageEditLinkForm' ) ;
if ( $form . length ) {
$form . WireTabs ( {
items : $ ( ".WireTab" ) ,
id : 'PageEditLinkTabs'
} ) ;
}
2022-03-08 15:55:41 +01:00
setTimeout ( function ( ) {
2024-04-04 14:37:20 +02:00
$ ( '#link_page_url_input' ) . trigger ( 'focus' ) ;
2022-03-08 15:55:41 +01:00
} , 250 ) ;
} ) ;