Diff
checker
文本
文本
图像
文档
Excel
文件夹
Legal
Enterprise
桌面版
定价
登录
下载 Diffchecker 桌面版
比较文本
查找两个文本文件之间的差异
工具
历史
显示
视图
拆分
统一
实时编辑器
隐藏空白更改
折叠未更改行
关闭换行
比对精度
智能
语法
无
更改外观
处理
忽略
文本转换
转到第一个差异
编辑输入
Diffchecker Desktop
运行Diffchecker最安全的方式。获取Diffchecker桌面应用:您的差异永远不会离开您的电脑!
获取桌面版
Start container controller diff
创建于
3天前
差异过期
4周后
清除
导出
分享
解释
45 删除
行
总计
删除
字符
总计
删除
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
163 行
全部复制
102 添加
行
总计
添加
字符
总计
添加
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
205 行
全部复制
import { raf } from '@utils/helpers';
import { raf } from '@utils/helpers';
import { isRTL } from '@utils/rtl';
import { isRTL } from '@utils/rtl';
/**
/**
* Applied to the host while the label is being repositioned. The
* Applied to the host while the label is being repositioned. The
* component stylesheets style this class, so it must stay in sync with
* component stylesheets style this class, so it must stay in sync with
* the `skip-label-transition` selector in those files. Renaming it here
* the `skip-label-transition` selector in those files. Renaming it here
* requires renaming it there too.
* requires renaming it there too.
*/
*/
export const SKIP_LABEL_TRANSITION_CLASS = 'skip-label-transition';
export const SKIP_LABEL_TRANSITION_CLASS = 'skip-label-transition';
/**
/**
* Set on the host as an inline style. The component stylesheets declare
* Set on the host as an inline style. The component stylesheets declare
* this property and read it with `var()`, so it must stay in sync with
* this property and read it with `var()`, so it must stay in sync with
* the `--internal-start-container-adjustment` references in those files.
* the `--internal-start-container-adjustment` references in those files.
* Renaming it here requires renaming it there too.
* Renaming it here requires renaming it there too.
*/
*/
export const START_CONTAINER_ADJUSTMENT_VAR = '--internal-start-container-adjustment';
export const START_CONTAINER_ADJUSTMENT_VAR = '--internal-start-container-adjustment';
/**
/**
复制
已复制
复制
已复制
* A utility to measure
and update
the start
container width adjustment
* Set on the host as an inline style. The component stylesheets declare
* for
form components
(input, textarea, select) with `fill="outline"`
.
* this property and read it with `var()`, so it must stay in sync with
* This adjustment compensates for
the
start container width
when
* the `--internal-start-end-container-width` references in those files.
* positioning
floating/stacked labels
with
in
the outline border.
* Renaming it here requires renaming it there too.
*/
export const START_END_CONTAINER_WIDTH_VAR = '--internal-start-end-container-width';
/**
* A utility to measure
the start
and end containers of
form components
*
(input, textarea, select) with `fill="outline"`
and write the results
* to
the
host. The
start container width
offsets
floating/stacked labels
* so they line up
with
the outline border.
The combined start and end
* container width lets the floating label size itself to the full width
* of the outline while still being positioned relative to the control.
*
*
* Measurement is deferred with raf() to avoid forcing layout during
* Measurement is deferred with raf() to avoid forcing layout during
* component updates, and a ResizeObserver watches for dynamic width
* component updates, and a ResizeObserver watches for dynamic width
* changes (e.g., when web fonts load or async content changes).
* changes (e.g., when web fonts load or async content changes).
*
*
* @internal
* @internal
* @param el - The host element (ion-input, ion-textarea, or ion-select).
* @param el - The host element (ion-input, ion-textarea, or ion-select).
* @param getStartContainer - A callback that returns the start container element.
* @param getStartContainer - A callback that returns the start container element.
复制
已复制
复制
已复制
* @param
shouldApplyAdjustment
- A callback that determines whether the
adjustment
should be
applied
.
* @param getEndContainer - A callback that returns the end container element.
* @param
shouldMeasure
- A callback that determines whether the
containers
should be
measured
.
*/
*/
复制
已复制
复制
已复制
export const createStart
ContainerController = (
export const createStart
End
ContainerController = (
el: HTMLElement,
el: HTMLElement,
getStartContainer: () => HTMLElement | undefined,
getStartContainer: () => HTMLElement | undefined,
复制
已复制
复制
已复制
shouldApplyAdjustment
: () => boolean
getEndContainer: () => HTMLElement | undefined,
): Start
ContainerController => {
shouldMeasure
: () => boolean
): Start
End
ContainerController => {
let resizeObserver: ResizeObserver | undefined;
let resizeObserver: ResizeObserver | undefined;
复制
已复制
复制
已复制
let
observedContainer
: HTMLElement | undefined;
let
observedStartContainer: HTMLElement | undefined;
let observedEndContainer
: HTMLElement | undefined;
let measurementRaf: number | undefined;
let measurementRaf: number | undefined;
let transitionRaf: number | undefined;
let transitionRaf: number | undefined;
let appliedAdjustment: string | undefined;
let appliedAdjustment: string | undefined;
复制
已复制
复制
已复制
let appliedStartEndWidth: string | undefined;
const calculateAdjustment = (): string => {
const startSlot = getStartContainer();
if (!startSlot || !shouldApplyAdjustment()) {
return '';
}
复制
已复制
复制
已复制
/*
/*
* Round to one decimal place so fractional widths produce a stable
* Round to one decimal place so fractional widths produce a stable
* label offset
when
the start
container is added, removed, or resized.
* label offset
and width
when
a
container is added, removed, or resized.
*/
*/
const startContainerWidth =
startSlot
.getBoundingClientRect().width
;
const roundWidth = (width: number) => Math.round(width * 10) / 10;
const
roundedWidth = Math.round(startContainerWidth * 10) / 10;
const measureContainers = (): { adjustment: string; startEndWidth: string } => {
const startContainer = getStartContainer();
if (!startContainer || !shouldMeasure()) {
return { adjustment: '', startEndWidth: '' };
}
const startContainerWidth =
roundWidth(startContainer
.getBoundingClientRect().width
)
;
const
endContainerWidth = roundWidth(getEndContainer()?.getBoundingClientRect().width ?? 0);
const sign = isRTL(el) ? '' : '-';
const sign = isRTL(el) ? '' : '-';
复制
已复制
复制
已复制
return
roundedWidth
? `${sign}${
roundedWidth
}px` : '0px'
;
return
{
adjustment: startContainerWidth
? `${sign}${
startContainerWidth
}px` : '0px'
,
startEndWidth: `${roundWidth(startContainerWidth + endContainerWidth)}px`,
}
;
};
};
复制
已复制
复制
已复制
const
scheduleAdjustmentUpdate
= () => {
const
scheduleMeasurement
= () => {
// Return if there is already a measurement queued to avoid a flicker
// Return if there is already a measurement queued to avoid a flicker
if (measurementRaf !== undefined) {
if (measurementRaf !== undefined) {
return;
return;
}
}
/*
/*
* Defer the measurement until the next animation frame so layout
* Defer the measurement until the next animation frame so layout
* is measured after the current update has been applied.
* is measured after the current update has been applied.
*/
*/
measurementRaf = raf(() => {
measurementRaf = raf(() => {
measurementRaf = undefined;
measurementRaf = undefined;
复制
已复制
复制
已复制
const
adjustment
= calculateAdjustment();
const
{
adjustment
, startEndWidth } = measureContainers();
/*
* The width only changes how much of the label fits, so it can
* animate. The transition is not suppressed here because the end
* container can change size while the label is floating, such as
* when async content loads, and that should not cut the float short.
*/
if (startEndWidth !== appliedStartEndWidth) {
el.style.setProperty(START_END_CONTAINER_WIDTH_VAR, startEndWidth);
appliedStartEndWidth = startEndWidth;
}
// Only suppress the label transition when the label has to move
// Only suppress the label transition when the label has to move
if (adjustment !== appliedAdjustment) {
if (adjustment !== appliedAdjustment) {
// Discard a removal queued by an earlier change
// Discard a removal queued by an earlier change
if (transitionRaf !== undefined) {
if (transitionRaf !== undefined) {
cancelAnimationFrame(transitionRaf);
cancelAnimationFrame(transitionRaf);
}
}
el.classList.add(SKIP_LABEL_TRANSITION_CLASS);
el.classList.add(SKIP_LABEL_TRANSITION_CLASS);
el.style.setProperty(START_CONTAINER_ADJUSTMENT_VAR, adjustment);
el.style.setProperty(START_CONTAINER_ADJUSTMENT_VAR, adjustment);
appliedAdjustment = adjustment;
appliedAdjustment = adjustment;
// Re-enable the transition once the new offset has been painted
// Re-enable the transition once the new offset has been painted
transitionRaf = raf(() => {
transitionRaf = raf(() => {
transitionRaf = undefined;
transitionRaf = undefined;
el.classList.remove(SKIP_LABEL_TRANSITION_CLASS);
el.classList.remove(SKIP_LABEL_TRANSITION_CLASS);
});
});
}
}
setupResizeObserver();
setupResizeObserver();
});
});
};
};
const disconnectResizeObserver = () => {
const disconnectResizeObserver = () => {
if (resizeObserver) {
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver.disconnect();
resizeObserver = undefined;
resizeObserver = undefined;
复制
已复制
复制
已复制
observedContainer
= undefined;
observedStartContainer = undefined;
observedEndContainer
= undefined;
}
}
};
};
const setupResizeObserver = () => {
const setupResizeObserver = () => {
复制
已复制
复制
已复制
const
startSlot
= getStartContainer();
const
startContainer
= getStartContainer();
const endContainer = getEndContainer();
复制
已复制
复制
已复制
// Stop watching once the
adjustment
no longer appl
ies
// Stop watching once the
measurements
no longer appl
y
if (!
startSlot
|| !
shouldApplyAdjustment
()) {
if (!
startContainer
|| !
shouldMeasure
()) {
disconnectResizeObserver();
disconnectResizeObserver();
return;
return;
}
}
复制
已复制
复制
已复制
// Return when prerendering or already watching th
is
container
// Return when prerendering or already watching th
ese
container
s
if (
typeof ResizeObserver !== 'function' ||
(resizeObserver && observed
Container ===
startSlot)
) {
if (
typeof ResizeObserver !== 'function' ||
(resizeObserver && observed
Start
Container ===
startContainer && observedEndContainer === endContainer)
) {
return;
return;
}
}
disconnectResizeObserver();
disconnectResizeObserver();
resizeObserver = new ResizeObserver(() => {
resizeObserver = new ResizeObserver(() => {
复制
已复制
复制
已复制
scheduleAdjustmentUpdate
();
scheduleMeasurement
();
});
});
复制
已复制
复制
已复制
observed
Container =
startSlot
;
observed
Start
Container =
startContainer
;
resizeObserver.observe(
startSlot);
resizeObserver.observe(
startContainer);
if (endContainer) {
observedEndContainer = endContainer;
resizeObserver.observe(endContainer);
}
};
};
复制
已复制
复制
已复制
const calculate
Start
ContainerWidth
= () => {
const calculate
ContainerWidth
s
= () => {
scheduleAdjustmentUpdate
();
scheduleMeasurement
();
};
};
const destroy = () => {
const destroy = () => {
disconnectResizeObserver();
disconnectResizeObserver();
if (measurementRaf !== undefined) {
if (measurementRaf !== undefined) {
cancelAnimationFrame(measurementRaf);
cancelAnimationFrame(measurementRaf);
measurementRaf = undefined;
measurementRaf = undefined;
}
}
// Tearing down mid-toggle would leave the transition disabled
// Tearing down mid-toggle would leave the transition disabled
if (transitionRaf !== undefined) {
if (transitionRaf !== undefined) {
cancelAnimationFrame(transitionRaf);
cancelAnimationFrame(transitionRaf);
transitionRaf = undefined;
transitionRaf = undefined;
el.classList.remove(SKIP_LABEL_TRANSITION_CLASS);
el.classList.remove(SKIP_LABEL_TRANSITION_CLASS);
}
}
// Re-apply from scratch if the element is connected again
// Re-apply from scratch if the element is connected again
appliedAdjustment = undefined;
appliedAdjustment = undefined;
复制
已复制
复制
已复制
appliedStartEndWidth = undefined;
};
};
return {
return {
复制
已复制
复制
已复制
calculate
Start
ContainerWidth
,
calculate
ContainerWidth
s
,
destroy,
destroy,
};
};
};
};
复制
已复制
复制
已复制
export type Start
ContainerController = {
export type Start
End
ContainerController = {
calculate
Start
ContainerWidth
: () => void;
calculate
ContainerWidth
s
: () => void;
destroy: () => void;
destroy: () => void;
};
};
已保存差异
原始文本
打开文件
import { raf } from '@utils/helpers'; import { isRTL } from '@utils/rtl'; /** * Applied to the host while the label is being repositioned. The * component stylesheets style this class, so it must stay in sync with * the `skip-label-transition` selector in those files. Renaming it here * requires renaming it there too. */ export const SKIP_LABEL_TRANSITION_CLASS = 'skip-label-transition'; /** * Set on the host as an inline style. The component stylesheets declare * this property and read it with `var()`, so it must stay in sync with * the `--internal-start-container-adjustment` references in those files. * Renaming it here requires renaming it there too. */ export const START_CONTAINER_ADJUSTMENT_VAR = '--internal-start-container-adjustment'; /** * A utility to measure and update the start container width adjustment * for form components (input, textarea, select) with `fill="outline"`. * This adjustment compensates for the start container width when * positioning floating/stacked labels within the outline border. * * Measurement is deferred with raf() to avoid forcing layout during * component updates, and a ResizeObserver watches for dynamic width * changes (e.g., when web fonts load or async content changes). * * @internal * @param el - The host element (ion-input, ion-textarea, or ion-select). * @param getStartContainer - A callback that returns the start container element. * @param shouldApplyAdjustment - A callback that determines whether the adjustment should be applied. */ export const createStartContainerController = ( el: HTMLElement, getStartContainer: () => HTMLElement | undefined, shouldApplyAdjustment: () => boolean ): StartContainerController => { let resizeObserver: ResizeObserver | undefined; let observedContainer: HTMLElement | undefined; let measurementRaf: number | undefined; let transitionRaf: number | undefined; let appliedAdjustment: string | undefined; const calculateAdjustment = (): string => { const startSlot = getStartContainer(); if (!startSlot || !shouldApplyAdjustment()) { return ''; } /* * Round to one decimal place so fractional widths produce a stable * label offset when the start container is added, removed, or resized. */ const startContainerWidth = startSlot.getBoundingClientRect().width; const roundedWidth = Math.round(startContainerWidth * 10) / 10; const sign = isRTL(el) ? '' : '-'; return roundedWidth ? `${sign}${roundedWidth}px` : '0px'; }; const scheduleAdjustmentUpdate = () => { // Return if there is already a measurement queued to avoid a flicker if (measurementRaf !== undefined) { return; } /* * Defer the measurement until the next animation frame so layout * is measured after the current update has been applied. */ measurementRaf = raf(() => { measurementRaf = undefined; const adjustment = calculateAdjustment(); // Only suppress the label transition when the label has to move if (adjustment !== appliedAdjustment) { // Discard a removal queued by an earlier change if (transitionRaf !== undefined) { cancelAnimationFrame(transitionRaf); } el.classList.add(SKIP_LABEL_TRANSITION_CLASS); el.style.setProperty(START_CONTAINER_ADJUSTMENT_VAR, adjustment); appliedAdjustment = adjustment; // Re-enable the transition once the new offset has been painted transitionRaf = raf(() => { transitionRaf = undefined; el.classList.remove(SKIP_LABEL_TRANSITION_CLASS); }); } setupResizeObserver(); }); }; const disconnectResizeObserver = () => { if (resizeObserver) { resizeObserver.disconnect(); resizeObserver = undefined; observedContainer = undefined; } }; const setupResizeObserver = () => { const startSlot = getStartContainer(); // Stop watching once the adjustment no longer applies if (!startSlot || !shouldApplyAdjustment()) { disconnectResizeObserver(); return; } // Return when prerendering or already watching this container if (typeof ResizeObserver !== 'function' || (resizeObserver && observedContainer === startSlot)) { return; } disconnectResizeObserver(); resizeObserver = new ResizeObserver(() => { scheduleAdjustmentUpdate(); }); observedContainer = startSlot; resizeObserver.observe(startSlot); }; const calculateStartContainerWidth = () => { scheduleAdjustmentUpdate(); }; const destroy = () => { disconnectResizeObserver(); if (measurementRaf !== undefined) { cancelAnimationFrame(measurementRaf); measurementRaf = undefined; } // Tearing down mid-toggle would leave the transition disabled if (transitionRaf !== undefined) { cancelAnimationFrame(transitionRaf); transitionRaf = undefined; el.classList.remove(SKIP_LABEL_TRANSITION_CLASS); } // Re-apply from scratch if the element is connected again appliedAdjustment = undefined; }; return { calculateStartContainerWidth, destroy, }; }; export type StartContainerController = { calculateStartContainerWidth: () => void; destroy: () => void; };
更改后文本
打开文件
import { raf } from '@utils/helpers'; import { isRTL } from '@utils/rtl'; /** * Applied to the host while the label is being repositioned. The * component stylesheets style this class, so it must stay in sync with * the `skip-label-transition` selector in those files. Renaming it here * requires renaming it there too. */ export const SKIP_LABEL_TRANSITION_CLASS = 'skip-label-transition'; /** * Set on the host as an inline style. The component stylesheets declare * this property and read it with `var()`, so it must stay in sync with * the `--internal-start-container-adjustment` references in those files. * Renaming it here requires renaming it there too. */ export const START_CONTAINER_ADJUSTMENT_VAR = '--internal-start-container-adjustment'; /** * Set on the host as an inline style. The component stylesheets declare * this property and read it with `var()`, so it must stay in sync with * the `--internal-start-end-container-width` references in those files. * Renaming it here requires renaming it there too. */ export const START_END_CONTAINER_WIDTH_VAR = '--internal-start-end-container-width'; /** * A utility to measure the start and end containers of form components * (input, textarea, select) with `fill="outline"` and write the results * to the host. The start container width offsets floating/stacked labels * so they line up with the outline border. The combined start and end * container width lets the floating label size itself to the full width * of the outline while still being positioned relative to the control. * * Measurement is deferred with raf() to avoid forcing layout during * component updates, and a ResizeObserver watches for dynamic width * changes (e.g., when web fonts load or async content changes). * * @internal * @param el - The host element (ion-input, ion-textarea, or ion-select). * @param getStartContainer - A callback that returns the start container element. * @param getEndContainer - A callback that returns the end container element. * @param shouldMeasure - A callback that determines whether the containers should be measured. */ export const createStartEndContainerController = ( el: HTMLElement, getStartContainer: () => HTMLElement | undefined, getEndContainer: () => HTMLElement | undefined, shouldMeasure: () => boolean ): StartEndContainerController => { let resizeObserver: ResizeObserver | undefined; let observedStartContainer: HTMLElement | undefined; let observedEndContainer: HTMLElement | undefined; let measurementRaf: number | undefined; let transitionRaf: number | undefined; let appliedAdjustment: string | undefined; let appliedStartEndWidth: string | undefined; /* * Round to one decimal place so fractional widths produce a stable * label offset and width when a container is added, removed, or resized. */ const roundWidth = (width: number) => Math.round(width * 10) / 10; const measureContainers = (): { adjustment: string; startEndWidth: string } => { const startContainer = getStartContainer(); if (!startContainer || !shouldMeasure()) { return { adjustment: '', startEndWidth: '' }; } const startContainerWidth = roundWidth(startContainer.getBoundingClientRect().width); const endContainerWidth = roundWidth(getEndContainer()?.getBoundingClientRect().width ?? 0); const sign = isRTL(el) ? '' : '-'; return { adjustment: startContainerWidth ? `${sign}${startContainerWidth}px` : '0px', startEndWidth: `${roundWidth(startContainerWidth + endContainerWidth)}px`, }; }; const scheduleMeasurement = () => { // Return if there is already a measurement queued to avoid a flicker if (measurementRaf !== undefined) { return; } /* * Defer the measurement until the next animation frame so layout * is measured after the current update has been applied. */ measurementRaf = raf(() => { measurementRaf = undefined; const { adjustment, startEndWidth } = measureContainers(); /* * The width only changes how much of the label fits, so it can * animate. The transition is not suppressed here because the end * container can change size while the label is floating, such as * when async content loads, and that should not cut the float short. */ if (startEndWidth !== appliedStartEndWidth) { el.style.setProperty(START_END_CONTAINER_WIDTH_VAR, startEndWidth); appliedStartEndWidth = startEndWidth; } // Only suppress the label transition when the label has to move if (adjustment !== appliedAdjustment) { // Discard a removal queued by an earlier change if (transitionRaf !== undefined) { cancelAnimationFrame(transitionRaf); } el.classList.add(SKIP_LABEL_TRANSITION_CLASS); el.style.setProperty(START_CONTAINER_ADJUSTMENT_VAR, adjustment); appliedAdjustment = adjustment; // Re-enable the transition once the new offset has been painted transitionRaf = raf(() => { transitionRaf = undefined; el.classList.remove(SKIP_LABEL_TRANSITION_CLASS); }); } setupResizeObserver(); }); }; const disconnectResizeObserver = () => { if (resizeObserver) { resizeObserver.disconnect(); resizeObserver = undefined; observedStartContainer = undefined; observedEndContainer = undefined; } }; const setupResizeObserver = () => { const startContainer = getStartContainer(); const endContainer = getEndContainer(); // Stop watching once the measurements no longer apply if (!startContainer || !shouldMeasure()) { disconnectResizeObserver(); return; } // Return when prerendering or already watching these containers if ( typeof ResizeObserver !== 'function' || (resizeObserver && observedStartContainer === startContainer && observedEndContainer === endContainer) ) { return; } disconnectResizeObserver(); resizeObserver = new ResizeObserver(() => { scheduleMeasurement(); }); observedStartContainer = startContainer; resizeObserver.observe(startContainer); if (endContainer) { observedEndContainer = endContainer; resizeObserver.observe(endContainer); } }; const calculateContainerWidths = () => { scheduleMeasurement(); }; const destroy = () => { disconnectResizeObserver(); if (measurementRaf !== undefined) { cancelAnimationFrame(measurementRaf); measurementRaf = undefined; } // Tearing down mid-toggle would leave the transition disabled if (transitionRaf !== undefined) { cancelAnimationFrame(transitionRaf); transitionRaf = undefined; el.classList.remove(SKIP_LABEL_TRANSITION_CLASS); } // Re-apply from scratch if the element is connected again appliedAdjustment = undefined; appliedStartEndWidth = undefined; }; return { calculateContainerWidths, destroy, }; }; export type StartEndContainerController = { calculateContainerWidths: () => void; destroy: () => void; };
查找差异