mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-02-28 21:20:28 +00:00
281 lines
6.0 KiB
TypeScript
281 lines
6.0 KiB
TypeScript
import { EventEmitter } from 'events';
|
|
|
|
const domReady = require('domready');
|
|
import Flags from './flags';
|
|
import { designer } from './editor';
|
|
|
|
function enterFullscreen() {
|
|
const elem = document.documentElement;
|
|
if (elem.requestFullscreen) {
|
|
elem.requestFullscreen();
|
|
}
|
|
}
|
|
|
|
function exitFullscreen() {
|
|
if (document.exitFullscreen) {
|
|
document.exitFullscreen();
|
|
}
|
|
}
|
|
|
|
function isFullscreen() {
|
|
return document.fullscreen || false;
|
|
}
|
|
|
|
interface IStyleResourceConfig {
|
|
media?: string;
|
|
type?: string;
|
|
content?: string;
|
|
}
|
|
|
|
class StyleResource {
|
|
config: IStyleResourceConfig;
|
|
styleElement: HTMLStyleElement;
|
|
mounted: boolean;
|
|
inited: boolean;
|
|
|
|
constructor(config: IStyleResourceConfig) {
|
|
this.config = config || {};
|
|
}
|
|
|
|
matchDevice(device: string) {
|
|
const media = this.config.media;
|
|
|
|
if (!media || media === 'ALL' || media === '*') {
|
|
return true;
|
|
}
|
|
|
|
return media.toUpperCase() === device.toUpperCase();
|
|
}
|
|
|
|
init() {
|
|
if (this.inited) {
|
|
return;
|
|
}
|
|
|
|
this.inited = true;
|
|
|
|
const { type, content } = this.config;
|
|
|
|
let styleElement: any;
|
|
if (type === 'URL') {
|
|
styleElement = document.createElement('link');
|
|
styleElement.href = content || '';
|
|
styleElement.rel = 'stylesheet';
|
|
} else {
|
|
styleElement = document.createElement('style');
|
|
styleElement.setAttribute('type', 'text/css');
|
|
if (styleElement.styleSheet) {
|
|
styleElement.styleSheet.cssText = content;
|
|
} else {
|
|
styleElement.appendChild(document.createTextNode(content || ''));
|
|
}
|
|
}
|
|
this.styleElement = styleElement;
|
|
}
|
|
|
|
apply() {
|
|
if (this.mounted) {
|
|
return;
|
|
}
|
|
|
|
this.init();
|
|
document.head.appendChild(this.styleElement);
|
|
this.mounted = true;
|
|
}
|
|
|
|
unmount() {
|
|
if (!this.mounted) {
|
|
return;
|
|
}
|
|
document.head.removeChild(this.styleElement);
|
|
this.mounted = false;
|
|
}
|
|
}
|
|
|
|
export class Viewport {
|
|
preview: boolean;
|
|
focused: boolean;
|
|
slateFixed: boolean;
|
|
emitter: EventEmitter;
|
|
device: string;
|
|
focusTarget: any;
|
|
cssResourceSet: StyleResource[];
|
|
|
|
constructor() {
|
|
this.preview = false;
|
|
this.emitter = new EventEmitter();
|
|
document.addEventListener('webkitfullscreenchange', () => {
|
|
this.emitter.emit('fullscreenchange', this.isFullscreen());
|
|
});
|
|
domReady(() => this.applyMediaCSS());
|
|
}
|
|
|
|
setFullscreen(flag: boolean) {
|
|
const fullscreen = this.isFullscreen();
|
|
if (fullscreen && !flag) {
|
|
exitFullscreen();
|
|
} else if (!fullscreen && flag) {
|
|
enterFullscreen();
|
|
}
|
|
}
|
|
|
|
toggleFullscreen() {
|
|
if (this.isFullscreen()) {
|
|
exitFullscreen();
|
|
} else {
|
|
enterFullscreen();
|
|
}
|
|
}
|
|
|
|
isFullscreen() {
|
|
return isFullscreen();
|
|
}
|
|
|
|
setFocus(flag: boolean) {
|
|
if (this.focused && !flag) {
|
|
this.focused = false;
|
|
Flags.remove('view-focused');
|
|
this.emitter.emit('focuschange', false);
|
|
} else if (!this.focused && flag) {
|
|
this.focused = true;
|
|
Flags.add('view-focused');
|
|
this.emitter.emit('focuschange', true);
|
|
}
|
|
}
|
|
|
|
setFocusTarget(focusTarget: any) {
|
|
this.focusTarget = focusTarget;
|
|
}
|
|
|
|
returnFocus() {
|
|
if (this.focusTarget) {
|
|
this.focusTarget.focus();
|
|
}
|
|
}
|
|
|
|
isFocus() {
|
|
return this.focused;
|
|
}
|
|
|
|
setPreview(flag: boolean) {
|
|
if (this.preview && !flag) {
|
|
this.preview = false;
|
|
Flags.setPreviewMode(false);
|
|
this.emitter.emit('preview', false);
|
|
this.changeViewport();
|
|
} else if (!this.preview && flag) {
|
|
this.preview = true;
|
|
Flags.setPreviewMode(true);
|
|
this.emitter.emit('preview', true);
|
|
this.changeViewport();
|
|
}
|
|
}
|
|
|
|
togglePreview() {
|
|
if (this.isPreview()) {
|
|
this.setPreview(false);
|
|
} else {
|
|
this.setPreview(true);
|
|
}
|
|
}
|
|
|
|
isPreview() {
|
|
return this.preview;
|
|
}
|
|
|
|
setDevice(device = 'pc') {
|
|
if (this.getDevice() !== device) {
|
|
this.device = device;
|
|
designer.currentDocument?.simulator?.set('device', device === 'mobile' ? 'mobile' : 'default');
|
|
// Flags.setSimulator(device);
|
|
// this.applyMediaCSS();
|
|
this.emitter.emit('devicechange', device);
|
|
this.changeViewport();
|
|
}
|
|
}
|
|
|
|
getDevice() {
|
|
return this.device || 'pc';
|
|
}
|
|
|
|
changeViewport() {
|
|
this.emitter.emit('viewportchange', this.getViewport());
|
|
}
|
|
|
|
getViewport() {
|
|
return `${this.isPreview() ? 'preview' : 'design'}-${this.getDevice()}`;
|
|
}
|
|
|
|
applyMediaCSS() {
|
|
if (!document.head || !this.cssResourceSet) {
|
|
return;
|
|
}
|
|
const device = this.getDevice();
|
|
this.cssResourceSet.forEach((item) => {
|
|
if (item.matchDevice(device)) {
|
|
item.apply();
|
|
} else {
|
|
item.unmount();
|
|
}
|
|
});
|
|
}
|
|
|
|
setGlobalCSS(resourceSet: IStyleResourceConfig[]) {
|
|
if (this.cssResourceSet) {
|
|
this.cssResourceSet.forEach((item) => {
|
|
item.unmount();
|
|
});
|
|
}
|
|
this.cssResourceSet = resourceSet.map((item: IStyleResourceConfig) => new StyleResource(item)).reverse();
|
|
this.applyMediaCSS();
|
|
}
|
|
|
|
setWithShell(shell: string) {
|
|
// Flags.setWithShell(shell);
|
|
}
|
|
|
|
onFullscreenChange(func: () => any) {
|
|
this.emitter.on('fullscreenchange', func);
|
|
return () => {
|
|
this.emitter.removeListener('fullscreenchange', func);
|
|
};
|
|
}
|
|
|
|
onPreview(func: () => any) {
|
|
this.emitter.on('preview', func);
|
|
return () => {
|
|
this.emitter.removeListener('preview', func);
|
|
};
|
|
}
|
|
|
|
onDeviceChange(func: () => any) {
|
|
this.emitter.on('devicechange', func);
|
|
return () => {
|
|
this.emitter.removeListener('devicechange', func);
|
|
};
|
|
}
|
|
|
|
onSlateFixedChange(func: (flag: boolean) => any) {
|
|
this.emitter.on('slatefixed', func);
|
|
return () => {
|
|
this.emitter.removeListener('slatefixed', func);
|
|
};
|
|
}
|
|
|
|
onViewportChange(func: () => any) {
|
|
this.emitter.on('viewportchange', func);
|
|
return () => {
|
|
this.emitter.removeListener('viewportchange', func);
|
|
};
|
|
}
|
|
|
|
onFocusChange(func: (flag: boolean) => any) {
|
|
this.emitter.on('focuschange', func);
|
|
return () => {
|
|
this.emitter.removeListener('focuschange', func);
|
|
};
|
|
}
|
|
}
|
|
|
|
export default new Viewport();
|