<!-- Created by henian.xu on 2020/5/18. -->

<template>
    <div
        :class="selfClasses"
        :style="selfStyles"
    >
        <div
            v-if="isRatio"
            class="mask"
            :style="maskStyles"
        ></div>
        <el-image
            v-bind="elImageProps"
            v-on="$listeners"
        >
            <slot
                name="placeholder"
                slot="placeholder"
            />
            <slot
                name="error"
                slot="error"
            />
        </el-image>
    </div>
</template>

<script>
export default {
    name: 'XImage',
    data() {
        return {};
    },
    props: {
        src: { type: String, default: '' },
        fit: { type: String, default: '' },
        lazy: Boolean,
        scrollContainer: {
            type: [String, HTMLElement],
            default: '',
        },
        previewSrcList: {
            type: [Array, Boolean],
            default: false,
        },
        zIndex: {
            type: Number,
            default: 2000,
        },
        // 自定义属性
        // 值必须是大于 0 的数值, 设置此值后组件的 display 为 block
        aspectRatio: {
            type: Number,
            default: 0,
            validator(val) {
                return val >= 0;
            },
        },
        width: {
            type: [String, Number],
            default: null,
        },
        height: {
            type: [String, Number],
            default: null,
        },
        radius: {
            type: [Boolean, String],
            default: '',
        },
        cut: {
            type: [String, Object],
            default: '',
        },
    },
    computed: {
        previewSrcList_() {
            const { previewSrcList, src } = this;
            if (this.$utils.isBoolean(previewSrcList) && previewSrcList && src) return [src];
            if (this.$utils.isArray(previewSrcList)) return previewSrcList;
            return [];
        },
        elImageProps() {
            const {
                cut,
                src,
                fit,
                lazy,
                scrollContainer,
                previewSrcList_: previewSrcList,
                zIndex,
                $attrs,
                // add
            } = this;
            return {
                ...$attrs,
                src: this.$options.filters.imgCropping(src, cut),
                fit,
                lazy,
                scrollContainer,
                previewSrcList,
                zIndex,
                // img 原生的属性，表示在获取资源时的引用方式
                // 有以下取值
                // "no-referrer" 表示HTTP头部信息将不会发送 referrer 。
                // "origin" 表示 referrer 只包含策略、主机名、端口等页面源的信息。
                // "unsafe-url" 这意味着引用者将包括源站和路径（但不包括片段、密码或用户名）。这种情况是不安全的，因为它可能会泄漏路径信息，这些信息已被使用TLS隐藏到第三方。
                // 'referrer-policy': $attrs['referrer-policy'] || $attrs.referrerPolicy,
            };
        },
        isRatio() {
            return !!this.aspectRatio;
        },
        selfClasses() {
            const { isRatio: ratio, radius } = this;
            return ['x-image', radius, { radius }, { ratio }];
        },
        selfStyles() {
            const { width, height, aspectRatio } = this;
            const w = this.$utils.transformCssValue(width) || undefined;
            const h = aspectRatio ? undefined : this.$utils.transformCssValue(height) || undefined;
            return {
                width: w,
                height: h,
            };
        },
        maskStyles() {
            const { aspectRatio } = this;
            if (!aspectRatio) return {};
            return {
                paddingTop: `${aspectRatio * 100}%`,
            };
        },
    },
};
</script>

<style lang="scss">
.x-image {
    display: inline-block;

    > .el-image {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: stretch;
        width: 100%;
        height: 100%;
        > .el-image__inner {
            flex: 1;
            display: block;
            height: auto;
        }
    }

    &.ratio {
        position: relative;
        display: block;
        > .el-image {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
        }
    }
    &.radius {
        > .el-image {
            border-radius: $padding-small;
        }
        &.all {
            > .el-image {
                border-radius: 100vw;
            }
        }
    }
}
</style>
