From 619cc9cba81a14ccbf0845f5fbdc8faec1116871 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 28 Jul 2024 18:14:01 +0300 Subject: [PATCH] implement link open in the new tab on middle button click --- .../Browser/Container/Page/Content/Markup.php | 78 +++++++++++++++++++ .../Container/Page/Content/Gemtext.php | 64 ++++++--------- 2 files changed, 101 insertions(+), 41 deletions(-) diff --git a/src/Abstract/Entity/Browser/Container/Page/Content/Markup.php b/src/Abstract/Entity/Browser/Container/Page/Content/Markup.php index 5a94afba..8a2d9a67 100644 --- a/src/Abstract/Entity/Browser/Container/Page/Content/Markup.php +++ b/src/Abstract/Entity/Browser/Container/Page/Content/Markup.php @@ -9,6 +9,8 @@ use \GtkLabel; use \Yggverse\Yoda\Entity\Browser\Container\Page\Content; +use \Yggverse\Net\Address; + abstract class Markup { public GtkLabel $gtk; @@ -121,4 +123,80 @@ abstract class Markup abstract public function set( string $value ): void; + + // Tools + protected function _line( + int $offset + ): ?string + { + if (is_null($this->_source)) + { + return null; + } + + $start = strrpos( + substr( + $this->_source, + 0, + $offset + ), + PHP_EOL + ) + 1; + + $end = strpos( + $this->_source, + PHP_EOL, + $offset + ); + + if ($end === false) + { + $end = strlen( + $this->_source + ); + } + + return substr( + $this->_source, + $start, + $end - $start + ); + } + + protected function _wrap( + string $source + ): string + { + if ($wrap = $this->_wrap ? $this->_wrap : $this::WRAP) + { + return wordwrap( + $source, + $wrap, + PHP_EOL, + false + ); + } + + throw new Exception; + } + + protected function _url( + string $link + ): ?string + { + $address = new Address( + $link + ); + + if ($address->isRelative()) + { + $address->toAbsolute( + new Address( + $this->content->page->navbar->request->getValue() + ) + ); + } + + return $address->get(); + } } diff --git a/src/Entity/Browser/Container/Page/Content/Gemtext.php b/src/Entity/Browser/Container/Page/Content/Gemtext.php index 59a1d960..7fce5312 100644 --- a/src/Entity/Browser/Container/Page/Content/Gemtext.php +++ b/src/Entity/Browser/Container/Page/Content/Gemtext.php @@ -20,7 +20,8 @@ use \Yggverse\Gemtext\Entity\Listing; use \Yggverse\Gemtext\Entity\Quote; use \Yggverse\Gemtext\Entity\Text; -use \Yggverse\Net\Address; +use \Yggverse\Gemtext\Parser\Link as LinkParser; + class Gemtext extends Markup { @@ -287,18 +288,36 @@ class Gemtext extends Markup GdkEvent $event ): bool { - // Open link in new tab on middle button click + // Open link in the new tab on middle button click if ($event->button->button == Gdk::BUTTON_MIDDLE) { + // Detect cursor position $result = $label->get_layout()->xy_to_index( $event->button->x * Pango::SCALE, $event->button->y * Pango::SCALE ); + // Position detected if ($result) { - // @TODO - return true; + // Get entire line from source + if ($line = $this->_line($result['index_'])) + { + // Parse gemtext href + if ($href = LinkParser::getAddress($line)) + { + // Format URL + if ($url = $this->_url($href)) + { + // Open + $this->content->page->container->tab->append( + $url + ); + + return true; + } + } + } } } @@ -313,41 +332,4 @@ class Gemtext extends Markup // @TODO return false; } - - private function _wrap( - string $source - ): string - { - if ($wrap = $this->_wrap ? $this->_wrap : $this::WRAP) - { - return wordwrap( - $source, - $wrap, - PHP_EOL, - false - ); - } - - throw new Exception; - } - - private function _url( - string $link - ): ?string - { - $address = new Address( - $link - ); - - if ($address->isRelative()) - { - $address->toAbsolute( - new Address( - $this->content->page->navbar->request->getValue() - ) - ); - } - - return $address->get(); - } } \ No newline at end of file