Fixed #4241 - Add Content Security Policy (CSP) config
parent
590504d137
commit
c42f45455c
|
@ -381,8 +381,8 @@ export default {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
handler(newValue) {
|
handler(newValue) {
|
||||||
if (!newValue) {
|
if (!newValue) {
|
||||||
loadStyle();
|
loadStyle(undefined, { nonce: this.$config?.csp?.nonce });
|
||||||
this.$options.css && this.$css.loadStyle();
|
this.$options.css && this.$css.loadStyle(undefined, { nonce: this.$config?.csp?.nonce });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,7 +395,7 @@ export default {
|
||||||
this._hook('onCreated');
|
this._hook('onCreated');
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
loadBaseStyle();
|
loadBaseStyle(undefined, { nonce: this.$config?.csp?.nonce });
|
||||||
this._loadGlobalStyles();
|
this._loadGlobalStyles();
|
||||||
this._hook('onBeforeMount');
|
this._hook('onBeforeMount');
|
||||||
},
|
},
|
||||||
|
@ -435,7 +435,7 @@ export default {
|
||||||
|
|
||||||
const globalCSS = this._getOptionValue(this.globalPT, 'global.css', this.$params);
|
const globalCSS = this._getOptionValue(this.globalPT, 'global.css', this.$params);
|
||||||
|
|
||||||
ObjectUtils.isNotEmpty(globalCSS) && loadGlobalStyle(globalCSS);
|
ObjectUtils.isNotEmpty(globalCSS) && loadGlobalStyle(globalCSS, { nonce: this.$config?.csp?.nonce });
|
||||||
},
|
},
|
||||||
_getHostInstance(instance) {
|
_getHostInstance(instance) {
|
||||||
return instance ? (this.$options.hostName ? (instance.$.type.name === this.$options.hostName ? instance : this._getHostInstance(instance.$parentInstance)) : instance.$parentInstance) : undefined;
|
return instance ? (this.$options.hostName ? (instance.$.type.name === this.$options.hostName ? instance : this._getHostInstance(instance.$parentInstance)) : instance.$parentInstance) : undefined;
|
||||||
|
@ -497,19 +497,22 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
globalPT() {
|
globalPT() {
|
||||||
return ObjectUtils.getItemValue(this.$primevue.config.pt, { instance: this });
|
return ObjectUtils.getItemValue(this.$config.pt, { instance: this });
|
||||||
},
|
},
|
||||||
defaultPT() {
|
defaultPT() {
|
||||||
return this._getOptionValue(this.$primevue.config.pt, this.$options.hostName || this.$.type.name, { instance: this }) || this.globalPT;
|
return this._getOptionValue(this.$config.pt, this.$options.hostName || this.$.type.name, { instance: this }) || this.globalPT;
|
||||||
},
|
},
|
||||||
isUnstyled() {
|
isUnstyled() {
|
||||||
return this.unstyled !== undefined ? this.unstyled : this.$primevue.config.unstyled;
|
return this.unstyled !== undefined ? this.unstyled : this.$config.unstyled;
|
||||||
},
|
},
|
||||||
$params() {
|
$params() {
|
||||||
return { instance: this, props: this.$props, state: this.$data, parentInstance: this.$parentInstance };
|
return { instance: this, props: this.$props, state: this.$data, parentInstance: this.$parentInstance };
|
||||||
},
|
},
|
||||||
$css() {
|
$css() {
|
||||||
return { classes: undefined, inlineStyles: undefined, loadStyle: () => {}, loadCustomStyle: () => {}, ...(this._getHostInstance(this) || {}).$css, ...this.$options.css };
|
return { classes: undefined, inlineStyles: undefined, loadStyle: () => {}, loadCustomStyle: () => {}, ...(this._getHostInstance(this) || {}).$css, ...this.$options.css };
|
||||||
|
},
|
||||||
|
$config() {
|
||||||
|
return this.$primevue?.config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,6 +57,7 @@ const BaseDirective = {
|
||||||
$binding: binding,
|
$binding: binding,
|
||||||
$el: $prevInstance['$el'] || undefined,
|
$el: $prevInstance['$el'] || undefined,
|
||||||
$css: { classes: undefined, inlineStyles: undefined, loadStyle: () => {}, ...options?.css },
|
$css: { classes: undefined, inlineStyles: undefined, loadStyle: () => {}, ...options?.css },
|
||||||
|
$config: config,
|
||||||
/* computed instance variables */
|
/* computed instance variables */
|
||||||
defaultPT: config?.pt?.directives?.[name],
|
defaultPT: config?.pt?.directives?.[name],
|
||||||
isUnstyled: el.unstyled !== undefined ? el.unstyled : config?.unstyled,
|
isUnstyled: el.unstyled !== undefined ? el.unstyled : config?.unstyled,
|
||||||
|
@ -78,8 +79,10 @@ const BaseDirective = {
|
||||||
handleHook('created', el, binding, vnode, prevVnode);
|
handleHook('created', el, binding, vnode, prevVnode);
|
||||||
},
|
},
|
||||||
beforeMount: (el, binding, vnode, prevVnode) => {
|
beforeMount: (el, binding, vnode, prevVnode) => {
|
||||||
loadBaseStyle();
|
const config = binding?.instance?.$primevue?.config;
|
||||||
!el.$instance?.isUnstyled && el.$instance?.$css?.loadStyle();
|
|
||||||
|
loadBaseStyle(undefined, { nonce: config?.csp?.nonce });
|
||||||
|
!el.$instance?.isUnstyled && el.$instance?.$css?.loadStyle(undefined, { nonce: config?.csp?.nonce });
|
||||||
handleHook('beforeMount', el, binding, vnode, prevVnode);
|
handleHook('beforeMount', el, binding, vnode, prevVnode);
|
||||||
},
|
},
|
||||||
mounted: (el, binding, vnode, prevVnode) => {
|
mounted: (el, binding, vnode, prevVnode) => {
|
||||||
|
|
|
@ -2582,6 +2582,7 @@ export default {
|
||||||
if (!this.responsiveStyleElement) {
|
if (!this.responsiveStyleElement) {
|
||||||
this.responsiveStyleElement = document.createElement('style');
|
this.responsiveStyleElement = document.createElement('style');
|
||||||
this.responsiveStyleElement.type = 'text/css';
|
this.responsiveStyleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.responsiveStyleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.body.appendChild(this.responsiveStyleElement);
|
document.body.appendChild(this.responsiveStyleElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -516,6 +516,7 @@ export default {
|
||||||
if (!this.carouselStyle) {
|
if (!this.carouselStyle) {
|
||||||
this.carouselStyle = document.createElement('style');
|
this.carouselStyle = document.createElement('style');
|
||||||
this.carouselStyle.type = 'text/css';
|
this.carouselStyle.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.carouselStyle, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.body.appendChild(this.carouselStyle);
|
document.body.appendChild(this.carouselStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ export interface PrimeVueConfiguration {
|
||||||
zIndex?: PrimeVueZIndexOptions;
|
zIndex?: PrimeVueZIndexOptions;
|
||||||
pt?: PrimeVuePTOptions;
|
pt?: PrimeVuePTOptions;
|
||||||
unstyled?: boolean;
|
unstyled?: boolean;
|
||||||
|
csp?: PrimeVueCSPOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PrimeVueZIndexOptions {
|
export interface PrimeVueZIndexOptions {
|
||||||
|
@ -112,6 +113,10 @@ export interface PrimeVueZIndexOptions {
|
||||||
tooltip?: number;
|
tooltip?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PrimeVueCSPOptions {
|
||||||
|
nonce?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PrimeVuePTOptions {
|
export interface PrimeVuePTOptions {
|
||||||
accordion?: DefaultPTOptions<AccordionPassThroughOptions>;
|
accordion?: DefaultPTOptions<AccordionPassThroughOptions>;
|
||||||
accordiontab?: DefaultPTOptions<AccordionTabPassThroughOptions>;
|
accordiontab?: DefaultPTOptions<AccordionTabPassThroughOptions>;
|
||||||
|
|
|
@ -132,7 +132,10 @@ export const defaultOptions = {
|
||||||
tooltip: 1100
|
tooltip: 1100
|
||||||
},
|
},
|
||||||
pt: undefined,
|
pt: undefined,
|
||||||
unstyled: false
|
unstyled: false,
|
||||||
|
csp: {
|
||||||
|
nonce: undefined
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const PrimeVueSymbol = Symbol();
|
const PrimeVueSymbol = Symbol();
|
||||||
|
|
|
@ -1852,12 +1852,14 @@ export default {
|
||||||
createStyleElement() {
|
createStyleElement() {
|
||||||
this.styleElement = document.createElement('style');
|
this.styleElement = document.createElement('style');
|
||||||
this.styleElement.type = 'text/css';
|
this.styleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.styleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.styleElement);
|
document.head.appendChild(this.styleElement);
|
||||||
},
|
},
|
||||||
createResponsiveStyle() {
|
createResponsiveStyle() {
|
||||||
if (!this.responsiveStyleElement) {
|
if (!this.responsiveStyleElement) {
|
||||||
this.responsiveStyleElement = document.createElement('style');
|
this.responsiveStyleElement = document.createElement('style');
|
||||||
this.responsiveStyleElement.type = 'text/css';
|
this.responsiveStyleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.responsiveStyleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.responsiveStyleElement);
|
document.head.appendChild(this.responsiveStyleElement);
|
||||||
|
|
||||||
let tableSelector = `.p-datatable-wrapper ${this.virtualScrollerDisabled ? '' : '> .p-virtualscroller'} > .p-datatable-table`;
|
let tableSelector = `.p-datatable-wrapper ${this.virtualScrollerDisabled ? '' : '> .p-virtualscroller'} > .p-datatable-table`;
|
||||||
|
|
|
@ -259,6 +259,7 @@ export default {
|
||||||
if (!this.styleElement && !this.isUnstyled) {
|
if (!this.styleElement && !this.isUnstyled) {
|
||||||
this.styleElement = document.createElement('style');
|
this.styleElement = document.createElement('style');
|
||||||
this.styleElement.type = 'text/css';
|
this.styleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.styleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.styleElement);
|
document.head.appendChild(this.styleElement);
|
||||||
|
|
||||||
let innerHTML = '';
|
let innerHTML = '';
|
||||||
|
|
|
@ -956,7 +956,7 @@ const classes = {
|
||||||
content: 'p-editor-content'
|
content: 'p-editor-content'
|
||||||
};
|
};
|
||||||
|
|
||||||
const { load: loadStyle } = useStyle(styles, { name: 'editor' });
|
const { load: loadStyle } = useStyle(styles, { name: 'editor', manual: true });
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'BaseEditor',
|
name: 'BaseEditor',
|
||||||
|
|
|
@ -424,6 +424,7 @@ export default {
|
||||||
if (!this.thumbnailsStyle) {
|
if (!this.thumbnailsStyle) {
|
||||||
this.thumbnailsStyle = document.createElement('style');
|
this.thumbnailsStyle = document.createElement('style');
|
||||||
this.thumbnailsStyle.type = 'text/css';
|
this.thumbnailsStyle.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.thumbnailsStyle, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.body.appendChild(this.thumbnailsStyle);
|
document.body.appendChild(this.thumbnailsStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,6 +482,7 @@ export default {
|
||||||
this.$el.setAttribute(this.attributeSelector, '');
|
this.$el.setAttribute(this.attributeSelector, '');
|
||||||
this.styleElement = document.createElement('style');
|
this.styleElement = document.createElement('style');
|
||||||
this.styleElement.type = 'text/css';
|
this.styleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.styleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.styleElement);
|
document.head.appendChild(this.styleElement);
|
||||||
|
|
||||||
let innerHTML = `
|
let innerHTML = `
|
||||||
|
|
|
@ -246,6 +246,7 @@ export default {
|
||||||
if (!this.styleElement && !this.isUnstyled) {
|
if (!this.styleElement && !this.isUnstyled) {
|
||||||
this.styleElement = document.createElement('style');
|
this.styleElement = document.createElement('style');
|
||||||
this.styleElement.type = 'text/css';
|
this.styleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.styleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.styleElement);
|
document.head.appendChild(this.styleElement);
|
||||||
|
|
||||||
let innerHTML = '';
|
let innerHTML = '';
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { UniqueComponentId } from 'primevue/utils';
|
import { DomHandler, UniqueComponentId } from 'primevue/utils';
|
||||||
import BasePaginator from './BasePaginator.vue';
|
import BasePaginator from './BasePaginator.vue';
|
||||||
import CurrrentPageReport from './CurrentPageReport.vue';
|
import CurrrentPageReport from './CurrentPageReport.vue';
|
||||||
import FirstPageLink from './FirstPageLink.vue';
|
import FirstPageLink from './FirstPageLink.vue';
|
||||||
|
@ -144,6 +144,7 @@ export default {
|
||||||
if (this.hasBreakpoints() && !this.isUnstyled) {
|
if (this.hasBreakpoints() && !this.isUnstyled) {
|
||||||
this.styleElement = document.createElement('style');
|
this.styleElement = document.createElement('style');
|
||||||
this.styleElement.type = 'text/css';
|
this.styleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.styleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.styleElement);
|
document.head.appendChild(this.styleElement);
|
||||||
|
|
||||||
let innerHTML = '';
|
let innerHTML = '';
|
||||||
|
|
|
@ -779,6 +779,7 @@ export default {
|
||||||
this.$el.setAttribute(this.attributeSelector, '');
|
this.$el.setAttribute(this.attributeSelector, '');
|
||||||
this.styleElement = document.createElement('style');
|
this.styleElement = document.createElement('style');
|
||||||
this.styleElement.type = 'text/css';
|
this.styleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.styleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.styleElement);
|
document.head.appendChild(this.styleElement);
|
||||||
|
|
||||||
let innerHTML = `
|
let innerHTML = `
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Portal from 'primevue/portal';
|
import Portal from 'primevue/portal';
|
||||||
import ToastEventBus from 'primevue/toasteventbus';
|
import ToastEventBus from 'primevue/toasteventbus';
|
||||||
import { ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primevue/utils';
|
import { DomHandler, ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primevue/utils';
|
||||||
import BaseToast from './BaseToast.vue';
|
import BaseToast from './BaseToast.vue';
|
||||||
import ToastMessage from './ToastMessage.vue';
|
import ToastMessage from './ToastMessage.vue';
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ export default {
|
||||||
if (!this.styleElement && !this.isUnstyled) {
|
if (!this.styleElement && !this.isUnstyled) {
|
||||||
this.styleElement = document.createElement('style');
|
this.styleElement = document.createElement('style');
|
||||||
this.styleElement.type = 'text/css';
|
this.styleElement.type = 'text/css';
|
||||||
|
DomHandler.setAttribute(this.styleElement, 'nonce', this.$primevue?.config?.csp?.nonce);
|
||||||
document.head.appendChild(this.styleElement);
|
document.head.appendChild(this.styleElement);
|
||||||
|
|
||||||
let innerHTML = '';
|
let innerHTML = '';
|
||||||
|
|
|
@ -5,6 +5,7 @@ export interface StyleOptions {
|
||||||
name?: string;
|
name?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
media?: string;
|
media?: string;
|
||||||
|
nonce?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function useStyle(
|
export declare function useStyle(
|
||||||
|
@ -15,6 +16,6 @@ export declare function useStyle(
|
||||||
name: string;
|
name: string;
|
||||||
css: any;
|
css: any;
|
||||||
unload: () => void;
|
unload: () => void;
|
||||||
load: () => void;
|
load: (css?: string, options?: any) => void;
|
||||||
isLoaded: boolean;
|
isLoaded: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@ export function useStyle(css, options = {}) {
|
||||||
const styleRef = ref(null);
|
const styleRef = ref(null);
|
||||||
|
|
||||||
const defaultDocument = DomHandler.isClient() ? window.document : undefined;
|
const defaultDocument = DomHandler.isClient() ? window.document : undefined;
|
||||||
const { document = defaultDocument, immediate = true, manual = false, name = `style_${++_id}`, id = undefined, media = undefined } = options;
|
const { document = defaultDocument, immediate = true, manual = false, name = `style_${++_id}`, id = undefined, media = undefined, nonce = undefined } = options;
|
||||||
|
|
||||||
let stop = () => {};
|
let stop = () => {};
|
||||||
|
|
||||||
|
@ -27,18 +27,21 @@ export function useStyle(css, options = {}) {
|
||||||
const load = (_css, _options = {}) => {
|
const load = (_css, _options = {}) => {
|
||||||
if (!document) return;
|
if (!document) return;
|
||||||
|
|
||||||
const [_name, _id] = [_options.name || name, _options.id || id];
|
const [_name, _id, _nonce] = [_options.name || name, _options.id || id, _options.nonce || nonce];
|
||||||
|
|
||||||
styleRef.value = document.querySelector(`style[data-primevue-style-id="${_name}"]`) || document.getElementById(_id) || document.createElement('style');
|
styleRef.value = document.querySelector(`style[data-primevue-style-id="${_name}"]`) || document.getElementById(_id) || document.createElement('style');
|
||||||
|
|
||||||
if (!styleRef.value.isConnected) {
|
if (!styleRef.value.isConnected) {
|
||||||
cssRef.value = _css || css;
|
cssRef.value = _css || css;
|
||||||
|
|
||||||
styleRef.value.type = 'text/css';
|
DomHandler.setAttributes(styleRef.value, {
|
||||||
_id && (styleRef.value.id = _id);
|
type: 'text/css',
|
||||||
media && (styleRef.value.media = media);
|
id: _id,
|
||||||
|
media,
|
||||||
|
nonce: _nonce
|
||||||
|
});
|
||||||
document.head.appendChild(styleRef.value);
|
document.head.appendChild(styleRef.value);
|
||||||
name && styleRef.value.setAttribute('data-primevue-style-id', name);
|
DomHandler.setAttribute(styleRef.value, 'data-primevue-style-id', name);
|
||||||
DomHandler.setAttributes(styleRef.value, _options);
|
DomHandler.setAttributes(styleRef.value, _options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,12 @@ export default {
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setAttribute(element, attribute = '', value) {
|
||||||
|
if (element && value !== null && value !== undefined) {
|
||||||
|
element.setAttribute(attribute, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setAttributes(element, attributes = {}) {
|
setAttributes(element, attributes = {}) {
|
||||||
if (element) {
|
if (element) {
|
||||||
const computedStyles = (rule, value) => {
|
const computedStyles = (rule, value) => {
|
||||||
|
|
|
@ -24,6 +24,7 @@ export declare class DomHandler {
|
||||||
static find(el: HTMLElement, selector: string): any[];
|
static find(el: HTMLElement, selector: string): any[];
|
||||||
static findSingle(el: HTMLElement, selector: string): any;
|
static findSingle(el: HTMLElement, selector: string): any;
|
||||||
static createElement(type: string, attributes: object, ...children: any): HTMLElement;
|
static createElement(type: string, attributes: object, ...children: any): HTMLElement;
|
||||||
|
static setAttribute(el: HTMLElement, attribute: string, value: any): void;
|
||||||
static setAttributes(el: HTMLElement, attributes: object): void;
|
static setAttributes(el: HTMLElement, attributes: object): void;
|
||||||
static getAttribute(el: HTMLElement, name: string): any;
|
static getAttribute(el: HTMLElement, name: string): any;
|
||||||
static isAttributeEquals(el: HTMLElement, name: string, value: any): boolean;
|
static isAttributeEquals(el: HTMLElement, name: string, value: any): boolean;
|
||||||
|
|
|
@ -65,7 +65,7 @@ const styles = `
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const { load: loadStyle } = useStyle(styles, { name: 'virtualscroller' });
|
const { load: loadStyle } = useStyle(styles, { name: 'virtualscroller', manual: true });
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'BaseVirtualScroller',
|
name: 'BaseVirtualScroller',
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<template>
|
||||||
|
<DocSectionText v-bind="$attrs">
|
||||||
|
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">nonce</a> value to use on dynamically generated style elements in core.</p>
|
||||||
|
|
||||||
|
<DocSectionCode :code="code1" hideToggleCode importCode hideCodeSandbox hideStackBlitz />
|
||||||
|
</DocSectionText>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
code1: {
|
||||||
|
basic: `app.use(PrimeVue, {
|
||||||
|
csp: {
|
||||||
|
nonce: '...'
|
||||||
|
}
|
||||||
|
});`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -22,6 +22,7 @@ import PTDoc from '@/doc/configuration/PTDoc.vue';
|
||||||
import RippleDoc from '@/doc/configuration/RippleDoc';
|
import RippleDoc from '@/doc/configuration/RippleDoc';
|
||||||
import UnstyledDoc from '@/doc/configuration/UnstyledDoc';
|
import UnstyledDoc from '@/doc/configuration/UnstyledDoc';
|
||||||
import ZIndexDoc from '@/doc/configuration/ZIndexDoc';
|
import ZIndexDoc from '@/doc/configuration/ZIndexDoc';
|
||||||
|
import NonceDoc from '@/doc/configuration/csp/NonceDoc';
|
||||||
import LocaleApiDoc from '@/doc/configuration/locale/LocaleApiDoc';
|
import LocaleApiDoc from '@/doc/configuration/locale/LocaleApiDoc';
|
||||||
import RepositoryDoc from '@/doc/configuration/locale/RepositoryDoc';
|
import RepositoryDoc from '@/doc/configuration/locale/RepositoryDoc';
|
||||||
import SetLocaleDoc from '@/doc/configuration/locale/SetLocaleDoc';
|
import SetLocaleDoc from '@/doc/configuration/locale/SetLocaleDoc';
|
||||||
|
@ -60,6 +61,17 @@ export default {
|
||||||
label: 'ZIndex',
|
label: 'ZIndex',
|
||||||
component: ZIndexDoc
|
component: ZIndexDoc
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'csp',
|
||||||
|
label: 'Content Security Policy (CSP)',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'nonce',
|
||||||
|
label: 'Nonce',
|
||||||
|
component: NonceDoc
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'locale',
|
id: 'locale',
|
||||||
label: 'Locale',
|
label: 'Locale',
|
||||||
|
|
Loading…
Reference in New Issue