/* * XmlDigitalTeaching v0.0.1 * Copyright ©Fri Mar 07 2025 11:35:13 GMT+0800 (中国标准时间) smile * Released under the ISC License. */ import Vue from 'vue'; const presetBgColors = ['#ede3fc', '#ffe4d2', '#ecebb4', '#fcdff6', '#d9f0b3', '#ccf1d9', '#bef1fe', '#fee6b4', '#cdedfc', '#dce8fa']; // var script$1 = { name: 'XmlLayoutRender', props: { //模式:preview 预览 (默认),editor 编辑 mode: { type: String, default: 'editor' }, //属性中传递过来的块儿数据 pBlockData: {}, //块儿数据名 blockDataName: String, //页面类型,取值h5、pc、pad pageType: { type: String, default: 'h5' }, resourceBasisPath: { type: String, default: '' }, //当前所处组的规则 currentRule: { type: Object, default: function () { return {}; } }, ruleIndex: Number, extendParams: { type: Object, default: function () { return {}; } }, bindingComponents: { type: Array, default: () => [] } }, data() { return { blockId: 'blockId' + Math.random(), blockData: { //当前块儿数据,一般用不到,因为一般的块儿中不会在块儿内更改数据 height: 'auto', rows: [1], columns: [1, 1], rowsUnit: 'fr', columnsUnit: 'fr', rowGap: 0, columnGap: 0, autoFlow: ['row', 'dense'], padding: [2, 2, 2, 2], areaBoxes: [] }, propertyComponentsName: 'xml-layout-property', //属性组件名 presetBgColors, refreshKey: 'mpk' + new Date().getTime() }; }, computed: { containerStyle() { let { height, padding, rows, columns, rowsUnit, columnsUnit, rowGap, columnGap, autoFlow } = this.blockData; let stringPadding = padding.map(item => item + 'px'); let gridTemplateRows = rows.map(item => item + rowsUnit).join(' '); let gridTemplateColumns = columns.map(item => item + columnsUnit).join(' '); return { display: 'grid', height: height === 'auto' ? 'auto' : `${height}px`, padding: stringPadding.join(' '), gridAutoFlow: autoFlow.join(' '), gridTemplateRows, gridTemplateColumns, gap: `${rowGap}px ${columnGap}px` }; }, injectedAreaBoxes() { return this.blockData.areaBoxes.filter(item => !!item.injectComponent?.data); }, spareAreaBoxes() { return this.blockData.areaBoxes.filter(item => !item.injectComponent?.data); }, isEmpty() { return !(this.blockData.recordSetList && this.blockData.recordSetList.length); } }, watch: { pBlockData: { handler(newValue) { this.$nextTick(() => { console.log('新data', newValue); this.blockData = Object.assign({}, this.blockData, newValue); }); }, deep: true, immediate: true } }, provide() { return { getCatalogList: () => ({ data: this.catalogList }), getCurrentRuleIndex: () => this.currentRuLeIndex, getXmlLayoutInstance: () => this }; }, methods: { // getAreaBoxMainIndex(uuid) { // return this.blockData.areaBoxes.findIndex(item => item.uuid === uuid) // }, // genAreaBoxStyle(areaBox,index) { // let { rowStart, rowEnd, columnStart, columnEnd } = areaBox // let target = index % this.presetBgColors.length // return { // '--areabox-color': this.presetBgColors[target], // gridRow: `${rowStart} / ${rowEnd}`, // gridColumn: `${columnStart} / ${columnEnd}`, // backgroundColor: `${this.presetBgColors[target]}66`, // 66透明度 // } // }, // spareAreaBoxClick(event, item) { // let rect = event.target.getBoundingClientRect() // this.$EventBus.$emit('areaBoxClick', { ...item, type: 'spare', rect }, { blockId: this.blockId, ruleIndex: this.ruleIndex}) // }, // 此方法必须要,用户注册块儿点击事件 blockClick() { this.$emit('blockclick', { blockData: this.blockData, dataName: this.blockDataName, propertyComponentsName: this.propertyComponentsName, blockId: this.blockId, ruleIndex: this.ruleIndex }); } }, created() {} }; function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { if (typeof shadowMode !== 'boolean') { createInjectorSSR = createInjector; createInjector = shadowMode; shadowMode = false; } // Vue.extend constructor export interop. const options = typeof script === 'function' ? script.options : script; // render functions if (template && template.render) { options.render = template.render; options.staticRenderFns = template.staticRenderFns; options._compiled = true; // functional template if (isFunctionalTemplate) { options.functional = true; } } // scopedId if (scopeId) { options._scopeId = scopeId; } let hook; if (moduleIdentifier) { // server build hook = function (context) { // 2.3 injection context = context || // cached call this.$vnode && this.$vnode.ssrContext || // stateful this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; // functional // 2.2 with runInNewContext: true if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { context = __VUE_SSR_CONTEXT__; } // inject component styles if (style) { style.call(this, createInjectorSSR(context)); } // register component module identifier for async chunk inference if (context && context._registeredComponents) { context._registeredComponents.add(moduleIdentifier); } }; // used by ssr in case component is cached and beforeCreate // never gets called options._ssrRegister = hook; } else if (style) { hook = shadowMode ? function (context) { style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot)); } : function (context) { style.call(this, createInjector(context)); }; } if (hook) { if (options.functional) { // register for functional component in vue file const originalRender = options.render; options.render = function renderWithStyleInjection(h, context) { hook.call(context); return originalRender(h, context); }; } else { // inject component registration as beforeCreate hook const existing = options.beforeCreate; options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; } } return script; } /* script */ const __vue_script__$1 = script$1; /* template */ var __vue_render__$1 = function () { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c( "div", { staticClass: "xml-layout-container", class: "xml-layout-container-" + _vm.pageType, attrs: { id: _vm.blockId }, on: { "!click": function ($event) { return _vm.blockClick.apply(null, arguments) }, }, }, [ _c("div", { class: ["xml-layout__wrapper", _vm.mode] }, [ _c( "div", { staticClass: "xml-grid-layout xml-grid-layout__container", style: _vm.containerStyle, }, [ _vm._t("default"), _vm._v(" "), _vm._l(_vm.blockData.areaBoxes, function (item, index) { return _c("XmlAreaBox", { key: item.uuid, attrs: { injected: _vm.bindingComponents.indexOf(item.uuid) !== -1, data: item, ruleIndex: _vm.ruleIndex, boxIndex: index, mode: _vm.mode, sign: _vm.currentRule.sign, }, }) }), ], 2 ), ]), ] ) }; var __vue_staticRenderFns__$1 = []; __vue_render__$1._withStripped = true; /* style */ const __vue_inject_styles__$1 = undefined; /* scoped */ const __vue_scope_id__$1 = undefined; /* module identifier */ const __vue_module_identifier__$1 = undefined; /* functional template */ const __vue_is_functional_template__$1 = false; /* style inject */ /* style inject SSR */ /* style inject shadow dom */ const __vue_component__$1 = /*#__PURE__*/normalizeComponent( { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 }, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, false, undefined, undefined, undefined ); /*! * portal-vue © Thorsten Lünborg, 2019 * * Version: 2.1.7 * * LICENCE: MIT * * https://github.com/linusborg/portal-vue * */ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } var inBrowser = typeof window !== 'undefined'; function freeze(item) { if (Array.isArray(item) || _typeof(item) === 'object') { return Object.freeze(item); } return item; } function combinePassengers(transports) { var slotProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return transports.reduce(function (passengers, transport) { var temp = transport.passengers[0]; var newPassengers = typeof temp === 'function' ? temp(slotProps) : transport.passengers; return passengers.concat(newPassengers); }, []); } function stableSort(array, compareFn) { return array.map(function (v, idx) { return [idx, v]; }).sort(function (a, b) { return compareFn(a[1], b[1]) || a[0] - b[0]; }).map(function (c) { return c[1]; }); } function pick(obj, keys) { return keys.reduce(function (acc, key) { if (obj.hasOwnProperty(key)) { acc[key] = obj[key]; } return acc; }, {}); } var transports = {}; var targets = {}; var sources = {}; var Wormhole = Vue.extend({ data: function data() { return { transports: transports, targets: targets, sources: sources, trackInstances: inBrowser }; }, methods: { open: function open(transport) { if (!inBrowser) return; var to = transport.to, from = transport.from, passengers = transport.passengers, _transport$order = transport.order, order = _transport$order === void 0 ? Infinity : _transport$order; if (!to || !from || !passengers) return; var newTransport = { to: to, from: from, passengers: freeze(passengers), order: order }; var keys = Object.keys(this.transports); if (keys.indexOf(to) === -1) { Vue.set(this.transports, to, []); } var currentIndex = this.$_getTransportIndex(newTransport); // Copying the array here so that the PortalTarget change event will actually contain two distinct arrays var newTransports = this.transports[to].slice(0); if (currentIndex === -1) { newTransports.push(newTransport); } else { newTransports[currentIndex] = newTransport; } this.transports[to] = stableSort(newTransports, function (a, b) { return a.order - b.order; }); }, close: function close(transport) { var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var to = transport.to, from = transport.from; if (!to || !from && force === false) return; if (!this.transports[to]) { return; } if (force) { this.transports[to] = []; } else { var index = this.$_getTransportIndex(transport); if (index >= 0) { // Copying the array here so that the PortalTarget change event will actually contain two distinct arrays var newTransports = this.transports[to].slice(0); newTransports.splice(index, 1); this.transports[to] = newTransports; } } }, registerTarget: function registerTarget(target, vm, force) { if (!inBrowser) return; if (this.trackInstances && !force && this.targets[target]) { console.warn("[portal-vue]: Target ".concat(target, " already exists")); } this.$set(this.targets, target, Object.freeze([vm])); }, unregisterTarget: function unregisterTarget(target) { this.$delete(this.targets, target); }, registerSource: function registerSource(source, vm, force) { if (!inBrowser) return; if (this.trackInstances && !force && this.sources[source]) { console.warn("[portal-vue]: source ".concat(source, " already exists")); } this.$set(this.sources, source, Object.freeze([vm])); }, unregisterSource: function unregisterSource(source) { this.$delete(this.sources, source); }, hasTarget: function hasTarget(to) { return !!(this.targets[to] && this.targets[to][0]); }, hasSource: function hasSource(to) { return !!(this.sources[to] && this.sources[to][0]); }, hasContentFor: function hasContentFor(to) { return !!this.transports[to] && !!this.transports[to].length; }, // Internal $_getTransportIndex: function $_getTransportIndex(_ref) { var to = _ref.to, from = _ref.from; for (var i in this.transports[to]) { if (this.transports[to][i].from === from) { return +i; } } return -1; } } }); var wormhole = new Wormhole(transports); var _id = 1; var Portal = Vue.extend({ name: 'portal', props: { disabled: { type: Boolean }, name: { type: String, default: function _default() { return String(_id++); } }, order: { type: Number, default: 0 }, slim: { type: Boolean }, slotProps: { type: Object, default: function _default() { return {}; } }, tag: { type: String, default: 'DIV' }, to: { type: String, default: function _default() { return String(Math.round(Math.random() * 10000000)); } } }, created: function created() { var _this = this; this.$nextTick(function () { wormhole.registerSource(_this.name, _this); }); }, mounted: function mounted() { if (!this.disabled) { this.sendUpdate(); } }, updated: function updated() { if (this.disabled) { this.clear(); } else { this.sendUpdate(); } }, beforeDestroy: function beforeDestroy() { wormhole.unregisterSource(this.name); this.clear(); }, watch: { to: function to(newValue, oldValue) { oldValue && oldValue !== newValue && this.clear(oldValue); this.sendUpdate(); } }, methods: { clear: function clear(target) { var closer = { from: this.name, to: target || this.to }; wormhole.close(closer); }, normalizeSlots: function normalizeSlots() { return this.$scopedSlots.default ? [this.$scopedSlots.default] : this.$slots.default; }, normalizeOwnChildren: function normalizeOwnChildren(children) { return typeof children === 'function' ? children(this.slotProps) : children; }, sendUpdate: function sendUpdate() { var slotContent = this.normalizeSlots(); if (slotContent) { var transport = { from: this.name, to: this.to, passengers: _toConsumableArray(slotContent), order: this.order }; wormhole.open(transport); } else { this.clear(); } } }, render: function render(h) { var children = this.$slots.default || this.$scopedSlots.default || []; var Tag = this.tag; if (children && this.disabled) { return children.length <= 1 && this.slim ? this.normalizeOwnChildren(children)[0] : h(Tag, [this.normalizeOwnChildren(children)]); } else { return this.slim ? h() : h(Tag, { class: { 'v-portal': true }, style: { display: 'none' }, key: 'v-portal-placeholder' }); } } }); var PortalTarget = Vue.extend({ name: 'portalTarget', props: { multiple: { type: Boolean, default: false }, name: { type: String, required: true }, slim: { type: Boolean, default: false }, slotProps: { type: Object, default: function _default() { return {}; } }, tag: { type: String, default: 'div' }, transition: { type: [String, Object, Function] } }, data: function data() { return { transports: wormhole.transports, firstRender: true }; }, created: function created() { var _this = this; this.$nextTick(function () { wormhole.registerTarget(_this.name, _this); }); }, watch: { ownTransports: function ownTransports() { this.$emit('change', this.children().length > 0); }, name: function name(newVal, oldVal) { /** * TODO * This should warn as well ... */ wormhole.unregisterTarget(oldVal); wormhole.registerTarget(newVal, this); } }, mounted: function mounted() { var _this2 = this; if (this.transition) { this.$nextTick(function () { // only when we have a transition, because it causes a re-render _this2.firstRender = false; }); } }, beforeDestroy: function beforeDestroy() { wormhole.unregisterTarget(this.name); }, computed: { ownTransports: function ownTransports() { var transports = this.transports[this.name] || []; if (this.multiple) { return transports; } return transports.length === 0 ? [] : [transports[transports.length - 1]]; }, passengers: function passengers() { return combinePassengers(this.ownTransports, this.slotProps); } }, methods: { // can't be a computed prop because it has to "react" to $slot changes. children: function children() { return this.passengers.length !== 0 ? this.passengers : this.$scopedSlots.default ? this.$scopedSlots.default(this.slotProps) : this.$slots.default || []; }, // can't be a computed prop because it has to "react" to this.children(). noWrapper: function noWrapper() { var noWrapper = this.slim && !this.transition; if (noWrapper && this.children().length > 1) { console.warn('[portal-vue]: PortalTarget with `slim` option received more than one child element.'); } return noWrapper; } }, render: function render(h) { var noWrapper = this.noWrapper(); var children = this.children(); var Tag = this.transition || this.tag; return noWrapper ? children[0] : this.slim && !Tag ? h() : h(Tag, { props: { // if we have a transition component, pass the tag if it exists tag: this.transition && this.tag ? this.tag : undefined }, class: { 'vue-portal-target': true } }, children); } }); var _id$1 = 0; var portalProps = ['disabled', 'name', 'order', 'slim', 'slotProps', 'tag', 'to']; var targetProps = ['multiple', 'transition']; Vue.extend({ name: 'MountingPortal', inheritAttrs: false, props: { append: { type: [Boolean, String] }, bail: { type: Boolean }, mountTo: { type: String, required: true }, // Portal disabled: { type: Boolean }, // name for the portal name: { type: String, default: function _default() { return 'mounted_' + String(_id$1++); } }, order: { type: Number, default: 0 }, slim: { type: Boolean }, slotProps: { type: Object, default: function _default() { return {}; } }, tag: { type: String, default: 'DIV' }, // name for the target to: { type: String, default: function _default() { return String(Math.round(Math.random() * 10000000)); } }, // Target multiple: { type: Boolean, default: false }, targetSlim: { type: Boolean }, targetSlotProps: { type: Object, default: function _default() { return {}; } }, targetTag: { type: String, default: 'div' }, transition: { type: [String, Object, Function] } }, created: function created() { if (typeof document === 'undefined') return; var el = document.querySelector(this.mountTo); if (!el) { console.error("[portal-vue]: Mount Point '".concat(this.mountTo, "' not found in document")); return; } var props = this.$props; // Target already exists if (wormhole.targets[props.name]) { if (props.bail) { console.warn("[portal-vue]: Target ".concat(props.name, " is already mounted.\n Aborting because 'bail: true' is set")); } else { this.portalTarget = wormhole.targets[props.name]; } return; } var append = props.append; if (append) { var type = typeof append === 'string' ? append : 'DIV'; var mountEl = document.createElement(type); el.appendChild(mountEl); el = mountEl; } // get props for target from $props // we have to rename a few of them var _props = pick(this.$props, targetProps); _props.slim = this.targetSlim; _props.tag = this.targetTag; _props.slotProps = this.targetSlotProps; _props.name = this.to; this.portalTarget = new PortalTarget({ el: el, parent: this.$parent || this, propsData: _props }); }, beforeDestroy: function beforeDestroy() { var target = this.portalTarget; if (this.append) { var el = target.$el; el.parentNode.removeChild(el); } target.$destroy(); }, render: function render(h) { if (!this.portalTarget) { console.warn("[portal-vue] Target wasn't mounted"); return h(); } // if there's no "manual" scoped slot, so we create a ourselves if (!this.$scopedSlots.manual) { var props = pick(this.$props, portalProps); return h(Portal, { props: props, attrs: this.$attrs, on: this.$listeners, scopedSlots: this.$scopedSlots }, this.$slots.default); } // else, we render the scoped slot var content = this.$scopedSlots.manual({ to: this.to }); // if user used