From 5dee42c7345c44ff054cf4dbf969af6c7255957b Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 3 Mar 2020 00:40:52 +0300 Subject: [PATCH] Improve handling of Instant View anchors. GitOrigin-RevId: 9293ea4c1c7f4767c7f91421b3719e00d836470c --- td/generate/scheme/td_api.tl | 13 ++++++--- td/generate/scheme/td_api.tlo | Bin 167500 -> 167696 bytes td/telegram/WebPageBlock.cpp | 50 ++++++++++++++++++++++++++++---- td/telegram/WebPageBlock.h | 3 +- td/telegram/WebPagesManager.cpp | 6 ++-- 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index b37016a36..222dd6133 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -843,8 +843,14 @@ richTextPhoneNumber text:RichText phone_number:string = RichText; //@height Height of a bounding box in which the image should be shown; 0 if unknown richTextIcon document:document width:int32 height:int32 = RichText; -//@description A rich text anchor @text Text @name Anchor name -richTextAnchor text:RichText name:string = RichText; +//@description A rich text reference of a text on the same web page @text The text @reference_text The text to show on click +richTextReference text:RichText reference_text:RichText = RichText; + +//@description An anchor @name Anchor name +richTextAnchor name:string = RichText; + +//@description A link to an anchor on the same web page @text The link text @name The anchor name +richTextAnchorLink text:RichText name:string = RichText; //@description A concatenation of rich texts @texts Texts richTexts texts:vector = RichText; @@ -980,10 +986,9 @@ pageBlockMap location:location zoom:int32 width:int32 height:int32 caption:pageB //@description Describes an instant view page for a web page @page_blocks Content of the web page //@version Version of the instant view, currently can be 1 or 2 -//@url Instant view URL; may be different from WebPage.url and must be used for the correct anchors handling //@is_rtl True, if the instant view must be shown from right to left //@is_full True, if the instant view contains the full page. A network request might be needed to get the full web page instant view -webPageInstantView page_blocks:vector version:int32 url:string is_rtl:Bool is_full:Bool = WebPageInstantView; +webPageInstantView page_blocks:vector version:int32 is_rtl:Bool is_full:Bool = WebPageInstantView; //@description Describes a web page preview diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 7e812e333810d948115e45168392c57f4825fe7c..01bdf0cb352be3774cee9b7ad662a41ae8b52e1e 100644 GIT binary patch delta 1104 zcmX>zhik$-t_>d)1aCyuNpl2cCTE1CR+KO>FbHmDRIKM>2~bKqG`U4vgOPjlTJ6g( zSU}3A9}s0!n7%}W(FTdjBFbn1;W~&i*1#oVAS?wj#t^ue!t@zpFvVb_zKAi}aDq$* z+RMN&y|ZQD19Ge$5%OyH4ZltD7fM-pZhs>Jpal8igpAqra* z8KF)uP-5HxF;PdEF$dkm?R!)hZ!kgRXQ(qSF@f2q3~@FCii4JlsU6tdCDZa9KgAJmv{VK=TN{@6fm%Vj79GEK zTnJT{Pi9^=+=)ODS~pgP*#s65@rnn?p9U1801 GB?tiJNLNAt delta 941 zcmbO*kL%1Ft_>d)1UE`o3vmQxCTE1CR+KO>Fz|0?RIKM>(c|W~oZOZQD19Ge$5%OyH4ZltD7fM-pZhs>Jpal8igpAqra* z8KF)uP-5HxF;PdEF$dkm?R!)hZ!kgRXQ(qSF@f2q3~@ anchors_; // anchor -> text }; static vector> get_page_block_objects( @@ -49,8 +56,6 @@ static vector> get_page_block_objects( }); } -namespace { - class RichText { static vector> get_rich_text_objects(const vector &rich_texts, GetWebPageBlockObjectContext *context) { @@ -112,6 +117,23 @@ class RichText { case RichText::Type::Fixed: return make_tl_object(texts[0].get_rich_text_object(context)); case RichText::Type::Url: + if (!context->base_url_.empty() && begins_with(content, context->base_url_) && + content.size() > context->base_url_.size() + 1 && content[context->base_url_.size()] == '#') { + if (context->is_first_pass_) { + context->has_anchor_urls_ = true; + } else { + auto anchor = Slice(content).substr(context->base_url_.size() + 1); + auto it = context->anchors_.find(anchor); + if (it != context->anchors_.end()) { + if (it->second == nullptr) { + return make_tl_object(texts[0].get_rich_text_object(context), anchor.str()); + } else { + return make_tl_object(texts[0].get_rich_text_object(context), + it->second->get_rich_text_object(context)); + } + } + } + } return make_tl_object(texts[0].get_rich_text_object(context), content, web_page_id.is_valid()); case RichText::Type::EmailAddress: @@ -134,7 +156,13 @@ class RichText { context->td_->documents_manager_->get_document_object(document_file_id), width, height); } case RichText::Type::Anchor: - return make_tl_object(texts[0].get_rich_text_object(context), content); + if (context->is_first_pass_) { + context->anchors_.emplace(Slice(content), texts[0].empty() ? nullptr : &texts[0]); + } + if (texts[0].empty()) { + return make_tl_object(content); + } + return texts[0].get_rich_text_object(context); } UNREACHABLE(); return nullptr; @@ -177,6 +205,8 @@ class RichText { } }; +namespace { + class WebPageBlockCaption { public: RichText text; @@ -740,6 +770,9 @@ class WebPageBlockAnchor : public WebPageBlock { } td_api::object_ptr get_page_block_object(Context *context) const override { + if (context->is_first_pass_) { + context->anchors_.emplace(name, nullptr); + } return make_tl_object(name); } @@ -2348,9 +2381,16 @@ vector> get_web_page_blocks( } vector> get_page_block_objects( - const vector> &page_blocks, Td *td) { + const vector> &page_blocks, Td *td, Slice base_url) { GetWebPageBlockObjectContext context; context.td_ = td; + context.base_url_ = base_url; + auto blocks = get_page_block_objects(page_blocks, &context); + if (context.anchors_.empty() || !context.has_anchor_urls_) { + return blocks; + } + + context.is_first_pass_ = false; return get_page_block_objects(page_blocks, &context); } diff --git a/td/telegram/WebPageBlock.h b/td/telegram/WebPageBlock.h index fc7b61345..e293558a3 100644 --- a/td/telegram/WebPageBlock.h +++ b/td/telegram/WebPageBlock.h @@ -14,6 +14,7 @@ #include "td/telegram/Photo.h" #include "td/utils/common.h" +#include "td/utils/Slice.h" #include @@ -103,6 +104,6 @@ vector> get_web_page_blocks( const std::unordered_map &videos, const std::unordered_map &voice_notes); vector> get_page_block_objects( - const vector> &page_blocks, Td *td); + const vector> &page_blocks, Td *td, Slice base_url); } // namespace td diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index d511d0c95..f7b5b1c18 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -1226,9 +1226,9 @@ tl_object_ptr WebPagesManager::get_web_page_instant_ LOG(ERROR) << "Trying to get not loaded web page instant view"; return nullptr; } - return make_tl_object(get_page_block_objects(web_page_instant_view->page_blocks, td_), - web_page_instant_view->is_v2 ? 2 : 1, web_page_instant_view->url, - web_page_instant_view->is_rtl, web_page_instant_view->is_full); + return td_api::make_object( + get_page_block_objects(web_page_instant_view->page_blocks, td_, web_page_instant_view->url), + web_page_instant_view->is_v2 ? 2 : 1, web_page_instant_view->is_rtl, web_page_instant_view->is_full); } void WebPagesManager::on_web_page_changed(WebPageId web_page_id, bool have_web_page) {