Skip to content

Commit

Permalink
Merge branch 'main' into 30820-fix-readme-lib
Browse files Browse the repository at this point in the history
  • Loading branch information
oidacra authored Dec 20, 2024
2 parents 6151243 + 7cc5143 commit 022088b
Show file tree
Hide file tree
Showing 17 changed files with 344 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
class="iframe-wrapper">
<iframe
(load)="onIframePageLoad()"
[src]="$editorProps().iframe.src | safeUrl"
[src]="uveStore.$iframeURL() | safeUrl"
[title]="host"
[ngStyle]="{
pointerEvents: $editorProps().iframe.pointerEvents,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ const messagesMock = {

const IFRAME_MOCK = {
nativeElement: {
addEventListener: function (_event, cb) {
this.registerListener.push(cb);
},
dispatchEvent: function (event) {
this.registerListener.forEach((cb) => cb(event));
},
registerListener: [],
contentWindow: document.defaultView,
contentDocument: {
getElementsByTagName: () => [],
querySelectorAll: () => [],
Expand Down Expand Up @@ -2614,7 +2622,7 @@ describe('EditEmaEditorComponent', () => {
const iframe = spectator.debugElement.query(By.css('[data-testId="iframe"]'));

expect(iframe.nativeElement.src).toBe(
'http://localhost:3000/index?clientHost=http%3A%2F%2Flocalhost%3A3000&language_id=1&com.dotmarketing.persona.id=modes.persona.no.persona&variantName=DEFAULT'
'http://localhost:3000/page-one?clientHost=http%3A%2F%2Flocalhost%3A3000&language_id=1&com.dotmarketing.persona.id=modes.persona.no.persona&variantName=DEFAULT'
);
});

Expand All @@ -2639,6 +2647,9 @@ describe('EditEmaEditorComponent', () => {
By.css('[data-testId="iframe"]')
);

iframe.nativeElement.dispatchEvent(new Event('load'));
spectator.detectChanges();

expect(iframe.nativeElement.contentDocument.body.innerHTML).toContain(
'<div>hello world</div>'
);
Expand All @@ -2665,11 +2676,14 @@ describe('EditEmaEditorComponent', () => {
language_id: '4',
'com.dotmarketing.persona.id': DEFAULT_PERSONA.identifier
});
spectator.detectChanges();

spectator.detectChanges();
jest.runOnlyPendingTimers();

expect(iframe.nativeElement.src).toBe('http://localhost/'); //When dont have src, the src is the same as the current page
iframe.nativeElement.dispatchEvent(new Event('load'));
spectator.detectChanges();

expect(iframe.nativeElement.src).toContain('about:blank'); //When dont have src, the src is the same as the current page
expect(iframe.nativeElement.contentDocument.body.innerHTML).toContain(
'<div>New Content - Hello World</div>'
);
Expand Down Expand Up @@ -2809,24 +2823,23 @@ describe('EditEmaEditorComponent', () => {

describe('script and styles injection', () => {
let iframeDocument: Document;
let iframeElement: HTMLIFrameElement;
let spy: jest.SpyInstance;

beforeEach(() => {
jest.spyOn(window, 'requestAnimationFrame').mockImplementation((cb) => {
cb(0); // Pass a dummy value to satisfy the expected argument count

return 0;
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
spectator.component.iframe = IFRAME_MOCK as any;
iframeDocument = spectator.component.iframe.nativeElement.contentDocument;
iframeElement = spectator.component.iframe.nativeElement;
iframeDocument = iframeElement.contentDocument;
spy = jest.spyOn(iframeDocument, 'write');
});

it('should add script and styles to iframe', () => {
spectator.component.setIframeContent(`<head></head></body></body>`);

iframeElement.dispatchEvent(new Event('load'));
spectator.detectChanges();

expect(spy).toHaveBeenCalled();
expect(iframeDocument.body.innerHTML).toContain(
`<script src="${SDK_EDITOR_SCRIPT_SOURCE}"></script>`
Expand All @@ -2842,6 +2855,9 @@ describe('EditEmaEditorComponent', () => {
it('should add script and styles to iframe for advance templates', () => {
spectator.component.setIframeContent(`<div>Advanced Template</div>`);

iframeElement.dispatchEvent(new Event('load'));
spectator.detectChanges();

expect(spy).toHaveBeenCalled();
expect(iframeDocument.body.innerHTML).toContain(
`<script src="${SDK_EDITOR_SCRIPT_SOURCE}"></script>`
Expand All @@ -2854,10 +2870,6 @@ describe('EditEmaEditorComponent', () => {
'[data-dot-object="contentlet"].empty-contentlet'
);
});

afterEach(() => {
(window.requestAnimationFrame as jest.Mock).mockRestore();
});
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,27 +192,14 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
return;
}

this.setIframeContent(code);

requestAnimationFrame(() => {
/**
* The status of isClientReady is changed outside of editor
* so we need to set it to true here to avoid the editor to be in a loading state
* This is only for traditional pages. For Headless, the isClientReady is set from the client application
*/
this.uveStore.setIsClientReady(true);
const win = this.contentWindow;
if (enableInlineEdit) {
this.inlineEditingService.injectInlineEdit(this.iframe);
} else {
this.inlineEditingService.removeInlineEdit(this.iframe);
}
this.setIframeContent(code, enableInlineEdit);

fromEvent(win, 'click').subscribe((e: MouseEvent) => {
this.handleInternalNav(e);
this.handleInlineEditing(e); // If inline editing is not active this will do nothing
});
});
/**
* The status of isClientReady is changed outside of editor
* so we need to set it to true here to avoid the editor to be in a loading state
* This is only for traditional pages. For Headless, the isClientReady is set from the client application
*/
this.uveStore.setIsClientReady(true);

return;
},
Expand Down Expand Up @@ -682,23 +669,53 @@ export class EditEmaEditorComponent implements OnInit, OnDestroy {
* @param code - The code to be added to the iframe.
* @memberof EditEmaEditorComponent
*/
setIframeContent(code: string) {
requestAnimationFrame(() => {
const doc = this.iframe?.nativeElement.contentDocument;
setIframeContent(code: string, enableInlineEdit = false): void {
const iframeElement = this.iframe?.nativeElement;

if (doc) {
const newFile = this.inyectCodeToVTL(code);
if (!iframeElement) {
return;
}

doc.open();
doc.write(newFile);
doc.close();
iframeElement.addEventListener('load', () => {
const doc = iframeElement.contentDocument;
const newDoc = this.inyectCodeToVTL(code);

this.uveStore.setOgTags(this.dotSeoMetaTagsUtilService.getMetaTags(doc));
this.ogTagsResults$ = this.dotSeoMetaTagsService
.getMetaTagsResults(doc)
.pipe(take(1));
if (!doc) {
return;
}

doc.open();
doc.write(newDoc);
doc.close();

this.uveStore.setOgTags(this.dotSeoMetaTagsUtilService.getMetaTags(doc));
this.ogTagsResults$ = this.dotSeoMetaTagsService.getMetaTagsResults(doc).pipe(take(1));
this.handleInlineScripts(enableInlineEdit);
});
}

/**
* Handle the Injection and removal of the inline editing scripts
*
* @param {boolean} enableInlineEdit
* @return {*}
* @memberof EditEmaEditorComponent
*/
handleInlineScripts(enableInlineEdit: boolean) {
const win = this.contentWindow;

fromEvent(win, 'click').subscribe((e: MouseEvent) => {
this.handleInternalNav(e);
this.handleInlineEditing(e); // If inline editing is not active this will do nothing
});

if (enableInlineEdit) {
this.inlineEditingService.injectInlineEdit(this.iframe);

return;
}

this.inlineEditingService.removeInlineEdit(this.iframe);
}

protected handleNgEvent({ event, actionPayload, clientAction }: DialogAction) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export interface EditorProps {
width: string;
height: string;
};
src: string;
pointerEvents: string;
opacity: string;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,23 @@ describe('withEditor', () => {
});
});

describe('$iframeURL', () => {
it("should return the iframe's URL", () => {
expect(store.$iframeURL()).toBe(
'http://localhost:3000/test-url?language_id=1&com.dotmarketing.persona.id=dot%3Apersona&variantName=DEFAULT&clientHost=http%3A%2F%2Flocalhost%3A3000'
);
});

it('should contain `about:blanck` in src when the page is traditional', () => {
patchState(store, {
pageAPIResponse: MOCK_RESPONSE_VTL,
isTraditionalPage: true
});

expect(store.$iframeURL()).toContain('about:blank');
});
});

describe('$editorProps', () => {
it('should return the expected data on init', () => {
expect(store.$editorProps()).toEqual({
Expand All @@ -651,7 +668,6 @@ describe('withEditor', () => {
iframe: {
opacity: '0.5',
pointerEvents: 'auto',
src: 'http://localhost:3000/test-url?language_id=1&com.dotmarketing.persona.id=dot%3Apersona&variantName=DEFAULT&clientHost=http%3A%2F%2Flocalhost%3A3000',
wrapper: null
},
progressBar: true,
Expand Down Expand Up @@ -720,15 +736,6 @@ describe('withEditor', () => {
expect(store.$editorProps().iframe.pointerEvents).toBe('none');
});

it('should have src as empty when the page is traditional', () => {
patchState(store, {
pageAPIResponse: MOCK_RESPONSE_VTL,
isTraditionalPage: true
});

expect(store.$editorProps().iframe.src).toBe('');
});

it('should have a wrapper when a device is present', () => {
const device = mockDotDevices[0] as DotDeviceWithIcon;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,29 @@ import {
PositionPayload
} from '../../../shared/models';
import {
sanitizeURL,
createPageApiUrlWithQueryParams,
mapContainerStructureToArrayOfContainers,
getPersonalization,
areContainersEquals,
getEditorStates
getEditorStates,
createPageApiUrlWithQueryParams,
sanitizeURL
} from '../../../utils';
import { UVEState } from '../../models';
import { withClient } from '../client/withClient';

const buildIframeURL = ({ pageURI, params, isTraditionalPage }) => {
if (isTraditionalPage) {
// Force iframe reload on every page load to avoid caching issues and window dirty state
return `about:blank?t=${Date.now()}`;
}

const pageAPIQueryParams = createPageApiUrlWithQueryParams(pageURI, params);
const origin = params.clientHost || window.location.origin;
const url = new URL(pageAPIQueryParams, origin);

return sanitizeURL(url.toString());
};

const initialState: EditorState = {
bounds: [],
state: EDITOR_STATE.IDLE,
Expand Down Expand Up @@ -122,10 +135,6 @@ export function withEditor() {

const { dragIsActive, isScrolling } = getEditorStates(state);

const url = sanitizeURL(params?.url);

const pageAPIQueryParams = createPageApiUrlWithQueryParams(url, params);

const showDialogs = canEditPage && isEditState;
const showBlockEditorSidebar = canEditPage && isEditState && isEnterprise;

Expand All @@ -142,8 +151,6 @@ export function withEditor() {
const shouldShowSeoResults = socialMedia && ogTags;

const iframeOpacity = isLoading || !isPageReady ? '0.5' : '1';
const origin = params.clientHost || window.location.origin;
const iframeURL = new URL(pageAPIQueryParams, origin);

return {
showDialogs,
Expand All @@ -152,7 +159,6 @@ export function withEditor() {
iframe: {
opacity: iframeOpacity,
pointerEvents: dragIsActive ? 'none' : 'auto',
src: !isTraditionalPage ? iframeURL.href : '',
wrapper: device
? {
width: `${device.cssWidth}${BASE_IFRAME_MEASURE_UNIT}`,
Expand Down Expand Up @@ -189,6 +195,16 @@ export function withEditor() {
}
: null
};
}),
$iframeURL: computed<string>(() => {
const page = store.pageAPIResponse().page;
const url = buildIframeURL({
pageURI: page?.pageURI,
params: store.pageParams(),
isTraditionalPage: untracked(() => store.isTraditionalPage())
});

return url;
})
};
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ export function withLoad() {
pageAsset?.page,
currentUser
);

const isTraditionalPage = !pageParams.clientHost;

patchState(store, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Params } from '@angular/router';

import { UVE_MODE } from '@dotcms/client';
import { CurrentUser } from '@dotcms/dotcms-js';
import {
DEFAULT_VARIANT_ID,
Expand All @@ -15,7 +14,7 @@ import {
import { EmaDragItem } from '../edit-ema-editor/components/ema-page-dropzone/types';
import { DotPageAssetKeys, DotPageApiParams } from '../services/dot-page-api.service';
import { COMMON_ERRORS, DEFAULT_PERSONA } from '../shared/consts';
import { EDITOR_STATE, PAGE_MODE } from '../shared/enums';
import { EDITOR_STATE } from '../shared/enums';
import {
ActionPayload,
ContainerPayload,
Expand Down Expand Up @@ -233,8 +232,7 @@ export function createPageApiUrlWithQueryParams(
language_id: params?.language_id ?? '1',
'com.dotmarketing.persona.id':
params?.['com.dotmarketing.persona.id'] ?? DEFAULT_PERSONA.identifier,
variantName: params?.variantName ?? DEFAULT_VARIANT_ID,
mode: params?.editorMode === UVE_MODE.PREVIEW ? PAGE_MODE.LIVE : params.mode
variantName: params?.variantName ?? DEFAULT_VARIANT_ID
};

// Filter out undefined values and url
Expand Down
10 changes: 0 additions & 10 deletions core-web/libs/sdk/client/src/lib/editor/sdk-editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,6 @@ describe('DotCMSPageEditor', () => {
lastScrollYPosition: 0
});
});

it('should isInsideEditor return false when is preview mode', () => {
Object.defineProperty(window, 'location', {
value: {
search: '?editorMode=preview'
},
writable: true
});
expect(isInsideEditor()).toBe(false);
});
});

describe('Add Class to Empty Contentets', () => {
Expand Down
Loading

0 comments on commit 022088b

Please sign in to comment.