Skip to content

Commit

Permalink
feat: add flag to update default slot text content
Browse files Browse the repository at this point in the history
add "experimentalDefaultSlotTextContentFix" flag to update text content of the default slot instead of update all the content

fixes one of the issues raised in ionic-team#5335
  • Loading branch information
yigityuce committed Feb 12, 2024
1 parent 0d9ed22 commit bc7023e
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/compiler/app-core/app-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export const updateBuildConditionals = (config: ValidatedConfig, b: BuildConditi
b.experimentalSlotFixes = config.extras.experimentalSlotFixes;
// TODO(STENCIL-1086): remove this option when it's the default behavior
b.experimentalScopedSlotChanges = config.extras.experimentalScopedSlotChanges;
b.experimentalDefaultSlotTextContentFix = config.extras.experimentalDefaultSlotTextContentFix;
// TODO(STENCIL-914): remove this option when `experimentalSlotFixes` is the default behavior
b.cloneNodeFix = config.extras.cloneNodeFix;
b.lifecycleDOMEvents = !!(b.isDebug || config._isTesting || config.extras.lifecycleDOMEvents);
Expand Down
10 changes: 10 additions & 0 deletions src/compiler/config/test/validate-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,16 @@ describe('validation', () => {
expect(config.extras.experimentalScopedSlotChanges).toBe(true);
});

it('should override experimentalScopedSlotChanges config based on `experimentalDefaultSlotTextContentFix`', () => {
userConfig.extras = {
experimentalScopedSlotChanges: false,
experimentalDefaultSlotTextContentFix: true,
} as any;
const { config } = validateConfig(userConfig, bootstrapConfig);
expect(config.extras.experimentalScopedSlotChanges).toBe(true);
expect(config.extras.experimentalDefaultSlotTextContentFix).toBe(true);
});

it('should set taskQueue "async" by default', () => {
const { config } = validateConfig(userConfig, bootstrapConfig);
expect(config.taskQueue).toBe('async');
Expand Down
23 changes: 21 additions & 2 deletions src/compiler/config/validate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,27 @@ export const validateConfig = (
validatedConfig.extras.scopedSlotTextContentFix = !!validatedConfig.extras.scopedSlotTextContentFix;
}

// TODO(STENCIL-1086): remove this option when it's the default behavior
validatedConfig.extras.experimentalScopedSlotChanges = !!validatedConfig.extras.experimentalScopedSlotChanges;
if (validatedConfig.extras.experimentalDefaultSlotTextContentFix === true) {
const possibleFlags: (keyof ConfigExtras)[] = ['experimentalScopedSlotChanges'];
const conflictingFlags = possibleFlags.filter((flag) => validatedConfig.extras[flag] === false);
if (conflictingFlags.length > 0) {
const warning = buildError(diagnostics);
warning.level = 'warn';
warning.messageText = `If the 'experimentalDefaultSlotTextContentFix' flag is enabled it will override the 'experimentalScopedSlotChanges' flag which are disabled. In particular, the following currently-disabled flags will be ignored: ${conflictingFlags.join(
', ',
)}. Please update your Stencil config accordingly.`;
}
}

validatedConfig.extras.experimentalDefaultSlotTextContentFix =
!!validatedConfig.extras.experimentalDefaultSlotTextContentFix;

if (validatedConfig.extras.experimentalDefaultSlotTextContentFix === true) {
validatedConfig.extras.experimentalScopedSlotChanges = true;
} else {
// TODO(STENCIL-1086): remove this option when it's the default behavior
validatedConfig.extras.experimentalScopedSlotChanges = !!validatedConfig.extras.experimentalScopedSlotChanges;
}

setBooleanConfig(
validatedConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const getHydrateBuildConditionals = (cmps: d.ComponentCompilerMeta[]) =>
build.experimentalSlotFixes = false;
// TODO(STENCIL-1086): remove this option when it's the default behavior
build.experimentalScopedSlotChanges = false;
build.experimentalDefaultSlotTextContentFix = false;
// TODO(STENCIL-914): remove this option when `experimentalSlotFixes` is the default behavior
build.cloneNodeFix = false;
build.cssAnnotations = true;
Expand Down
1 change: 1 addition & 0 deletions src/declarations/stencil-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export interface BuildConditionals extends Partial<BuildFeatures> {
experimentalSlotFixes?: boolean;
// TODO(STENCIL-1086): remove this option when it's the default behavior
experimentalScopedSlotChanges?: boolean;
experimentalDefaultSlotTextContentFix?: boolean;
}

export type ModuleFormat =
Expand Down
9 changes: 9 additions & 0 deletions src/declarations/stencil-public-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,15 @@ interface ConfigExtrasBase {
* Defaults to `false`.
*/
experimentalScopedSlotChanges?: boolean;

/**
* Experimental flag.
* Updates the behavior defined with {@link experimentalScopedSlotChanges} of scoped components
* to modify only the default slot's text content instead all the content of host element.
*
* Defaults to `false`.
*/
experimentalDefaultSlotTextContentFix?: boolean;
}

// TODO(STENCIL-914): delete this interface when `experimentalSlotFixes` is the default behavior
Expand Down
17 changes: 12 additions & 5 deletions src/runtime/dom-extras.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,10 @@ export const patchTextContent = (hostElementPrototype: HTMLElement): void => {
// To mimic shadow root behavior, we need to return the text content of all
// nodes in a slot reference node
get(): string | null {
const slotRefNodes = getAllChildSlotNodes(this.childNodes);
let slotRefNodes = getAllChildSlotNodes(this.childNodes, this.tagName);
if (BUILD.experimentalDefaultSlotTextContentFix) {
slotRefNodes = slotRefNodes.filter((node) => node['s-sn'] === '');
}

const textContent = slotRefNodes
.map((node) => {
Expand Down Expand Up @@ -295,7 +298,10 @@ export const patchTextContent = (hostElementPrototype: HTMLElement): void => {
// reference node. If a default slot reference node exists, the text content will be
// placed there. Otherwise, the new text node will be hidden
set(value: string | null) {
const slotRefNodes = getAllChildSlotNodes(this.childNodes);
let slotRefNodes = getAllChildSlotNodes(this.childNodes, this.tagName);
if (BUILD.experimentalDefaultSlotTextContentFix) {
slotRefNodes = slotRefNodes.filter((node) => node['s-sn'] === '');
}

slotRefNodes.forEach((node) => {
// Remove the existing content of the slot
Expand Down Expand Up @@ -410,16 +416,17 @@ export const patchChildSlotNodes = (elm: HTMLElement, cmpMeta: d.ComponentRuntim
* Recursively finds all slot reference nodes ('s-sr') in a series of child nodes.
*
* @param childNodes The set of child nodes to search for slot reference nodes.
* @param hostName The host component name to search for slot hostname.
* @returns An array of slot reference nodes.
*/
const getAllChildSlotNodes = (childNodes: NodeListOf<ChildNode>): d.RenderNode[] => {
const getAllChildSlotNodes = (childNodes: NodeListOf<ChildNode>, hostName: string): d.RenderNode[] => {
const slotRefNodes = [];

for (const childNode of Array.from(childNodes) as d.RenderNode[]) {
if (childNode['s-sr']) {
if (childNode['s-sr'] && hostName === childNode['s-hn']) {
slotRefNodes.push(childNode);
}
slotRefNodes.push(...getAllChildSlotNodes(childNode.childNodes));
slotRefNodes.push(...getAllChildSlotNodes(childNode.childNodes, hostName));
}

return slotRefNodes;
Expand Down
1 change: 1 addition & 0 deletions src/testing/reset-build-conditionals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ export function resetBuildConditionals(b: d.BuildConditionals) {
b.experimentalSlotFixes = false;
// TODO(STENCIL-1086): remove this option when it's the default behavior
b.experimentalScopedSlotChanges = false;
b.experimentalDefaultSlotTextContentFix = false;
}

0 comments on commit bc7023e

Please sign in to comment.