Skip to content

Commit

Permalink
Add support for MountableSpan interface
Browse files Browse the repository at this point in the history
Summary:
This diff introduces the `MountableSpan` interface that can be added to custom spans to receive callback with the hosting View when the component is mounted or unmounted.

This approach was also discussed in the scope of the [Composable and Extensible span RFC for Bloks](https://docs.google.com/document/d/1EKlAx9dMWsrltmmN1Ge9NfsXSycSXKwCLcmoCoxbwlE/edit?tab=t.0#bookmark=id.l3rxz5cm5xj2) but it was never implemented.

Now this interface is used for the GenAI use case implemented in the next diff.

Reviewed By: zielinskimz

Differential Revision: D64940916

fbshipit-source-id: 12b4f1647e6e7f88f54078f598d9522a0c39589c
  • Loading branch information
AlexBalo authored and facebook-github-bot committed Oct 28, 2024
1 parent 7396934 commit 10c078b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.facebook.rendercore.text

import android.view.View

/**
* A span interface that allows users to receive callbacks when the hosting [View] is mounted and
* unmounted so that it is possible to the component to get access to it..
*/
interface MountableSpan {

fun onMount(view: View)

fun onUnmount(view: View)
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public void draw(Canvas canvas) {
shouldRestore = true;
}

final OnPrePostDrawSpan[] onPrePostDrawSpans = getOnPrePostDrawableSpans();
final OnPrePostDrawSpan[] onPrePostDrawSpans = getOnPrePostDrawSpans();
if (onPrePostDrawSpans.length == 0) {
drawLayout(canvas);
} else {
Expand Down Expand Up @@ -174,13 +174,20 @@ private void drawLayout(Canvas canvas) {
mLayout.draw(canvas, getSelectionPath(), mHighlightPaint, 0);
}

private OnPrePostDrawSpan[] getOnPrePostDrawableSpans() {
private OnPrePostDrawSpan[] getOnPrePostDrawSpans() {
if (!(mText instanceof Spanned)) {
return new OnPrePostDrawSpan[0];
}
return ((Spanned) mText).getSpans(0, mText.length(), OnPrePostDrawSpan.class);
}

private MountableSpan[] getMountableSpans() {
if (!(mText instanceof Spanned)) {
return new MountableSpan[0];
}
return ((Spanned) mText).getSpans(0, mText.length(), MountableSpan.class);
}

public void mount(TextLayout textLayout) {
final ColorStateList colorStateList = textLayout.textStyle.textColorStateList;
mText = textLayout.processedText;
Expand Down Expand Up @@ -231,6 +238,11 @@ public void mount(TextLayout textLayout) {
if (textLayout.textStyle.accessibilityLabel != null) {
setContentDescription(textLayout.textStyle.accessibilityLabel);
}

final MountableSpan[] mountableSpans = getMountableSpans();
for (MountableSpan mountableSpan : mountableSpans) {
mountableSpan.onMount(this);
}
invalidate();
}

Expand All @@ -239,6 +251,10 @@ public boolean isTextTruncated() {
}

public void unmount() {
final MountableSpan[] mountableSpans = getMountableSpans();
for (MountableSpan mountableSpan : mountableSpans) {
mountableSpan.onUnmount(this);
}
// NULLSAFE_FIXME[Field Not Nullable]
mText = null;
// NULLSAFE_FIXME[Field Not Nullable]
Expand Down

0 comments on commit 10c078b

Please sign in to comment.