Website Structure
This commit is contained in:
parent
62812f2090
commit
71f0676a62
22365 changed files with 4265753 additions and 791 deletions
65
Frontend-Learner/node_modules/quasar/src/plugins/addressbar/AddressbarColor.js
generated
vendored
Normal file
65
Frontend-Learner/node_modules/quasar/src/plugins/addressbar/AddressbarColor.js
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { client } from '../platform/Platform.js'
|
||||
import { noop } from '../../utils/event/event.js'
|
||||
import getCssVar from '../../utils/css-var/get-css-var.js'
|
||||
|
||||
let metaValue
|
||||
|
||||
function getProp () {
|
||||
return client.is.winphone
|
||||
? 'msapplication-navbutton-color'
|
||||
: 'theme-color' // Safari, Chrome, ...
|
||||
}
|
||||
|
||||
function getMetaTag (v) {
|
||||
const els = document.getElementsByTagName('META')
|
||||
for (const i in els) {
|
||||
if (els[ i ].name === v) {
|
||||
return els[ i ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setColor (hexColor) {
|
||||
if (metaValue === void 0) {
|
||||
// cache it
|
||||
metaValue = getProp()
|
||||
}
|
||||
|
||||
let metaTag = getMetaTag(metaValue)
|
||||
const newTag = metaTag === void 0
|
||||
|
||||
if (newTag) {
|
||||
metaTag = document.createElement('meta')
|
||||
metaTag.setAttribute('name', metaValue)
|
||||
}
|
||||
|
||||
metaTag.setAttribute('content', hexColor)
|
||||
|
||||
if (newTag) {
|
||||
document.head.appendChild(metaTag)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
set: __QUASAR_SSR_SERVER__ !== true && client.is.mobile === true && (
|
||||
client.is.nativeMobile === true
|
||||
|| client.is.winphone === true || client.is.safari === true
|
||||
|| client.is.webkit === true || client.is.vivaldi === true
|
||||
)
|
||||
? hexColor => {
|
||||
const val = hexColor || getCssVar('primary')
|
||||
|
||||
if (client.is.nativeMobile === true && window.StatusBar) {
|
||||
window.StatusBar.backgroundColorByHexString(val)
|
||||
}
|
||||
else {
|
||||
setColor(val)
|
||||
}
|
||||
}
|
||||
: noop,
|
||||
|
||||
install ({ $q }) {
|
||||
$q.addressbarColor = this
|
||||
$q.config.addressbarColor && this.set($q.config.addressbarColor)
|
||||
}
|
||||
}
|
||||
22
Frontend-Learner/node_modules/quasar/src/plugins/addressbar/AddressbarColor.json
generated
vendored
Normal file
22
Frontend-Learner/node_modules/quasar/src/plugins/addressbar/AddressbarColor.json
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/addressbar-color"
|
||||
},
|
||||
|
||||
"injection": "$q.addressbarColor",
|
||||
|
||||
"methods": {
|
||||
"set": {
|
||||
"desc": "Sets addressbar color (for browsers that support it)",
|
||||
"params": {
|
||||
"hexColor": {
|
||||
"type": "String",
|
||||
"desc": "Color in hex format",
|
||||
"required": true,
|
||||
"examples": [ "'#ff0000'" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Frontend-Learner/node_modules/quasar/src/plugins/addressbar/AddressbarColor.test.js
generated
vendored
Normal file
53
Frontend-Learner/node_modules/quasar/src/plugins/addressbar/AddressbarColor.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { describe, test, expect, vi } from 'vitest'
|
||||
import { mount, config } from '@vue/test-utils'
|
||||
|
||||
import AddressbarColor from './AddressbarColor.js'
|
||||
|
||||
// We override Quasar install so it installs this plugin
|
||||
const quasarVuePlugin = config.global.plugins.find(entry => entry.name === 'Quasar')
|
||||
const { install } = quasarVuePlugin
|
||||
|
||||
function mountPlugin (addressbarColor) {
|
||||
quasarVuePlugin.install = app => install(app, {
|
||||
config: { addressbarColor },
|
||||
plugins: { AddressbarColor }
|
||||
})
|
||||
|
||||
return mount({ template: '<div />' })
|
||||
}
|
||||
|
||||
describe('[AddressbarColor API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
expect(AddressbarColor).toBe(wrapper.vm.$q.addressbarColor)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)set]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(
|
||||
AddressbarColor.set('#ff0000')
|
||||
).toBeUndefined()
|
||||
})
|
||||
|
||||
test('should be called automatically when $q.config.addressbarColor is set', () => {
|
||||
const original = AddressbarColor.set
|
||||
|
||||
// override original since the real test would be on a
|
||||
// mobile platform (and we can't test that here, yet)
|
||||
AddressbarColor.set = vi.fn()
|
||||
mountPlugin('#aabbcc')
|
||||
|
||||
expect.soft(AddressbarColor.set).toHaveBeenCalledTimes(1)
|
||||
expect.soft(AddressbarColor.set).toHaveBeenCalledWith('#aabbcc')
|
||||
|
||||
// restore original
|
||||
AddressbarColor.set = original
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
127
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/AppFullscreen.js
generated
vendored
Normal file
127
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/AppFullscreen.js
generated
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
import { changeGlobalNodesTarget } from '../../utils/private.config/nodes.js'
|
||||
|
||||
const prefixes = {}
|
||||
|
||||
function assignFn (fn) {
|
||||
Object.assign(Plugin, {
|
||||
request: fn,
|
||||
exit: fn,
|
||||
toggle: fn
|
||||
})
|
||||
}
|
||||
|
||||
function getFullscreenElement () {
|
||||
return (
|
||||
document.fullscreenElement
|
||||
|| document.mozFullScreenElement
|
||||
|| document.webkitFullscreenElement
|
||||
|| document.msFullscreenElement
|
||||
|| null
|
||||
)
|
||||
}
|
||||
|
||||
function updateEl () {
|
||||
const newEl = Plugin.activeEl = Plugin.isActive === false
|
||||
? null
|
||||
: getFullscreenElement()
|
||||
|
||||
changeGlobalNodesTarget(
|
||||
newEl === null || newEl === document.documentElement
|
||||
? document.body
|
||||
: newEl
|
||||
)
|
||||
}
|
||||
|
||||
function togglePluginState () {
|
||||
Plugin.isActive = Plugin.isActive === false
|
||||
updateEl()
|
||||
}
|
||||
|
||||
// needed for consistency across browsers
|
||||
function promisify (target, fn) {
|
||||
try {
|
||||
const res = target[ fn ]()
|
||||
return res === void 0
|
||||
? Promise.resolve()
|
||||
: res
|
||||
}
|
||||
catch (err) {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
}
|
||||
|
||||
const Plugin = createReactivePlugin({
|
||||
isActive: false,
|
||||
activeEl: null
|
||||
}, {
|
||||
isCapable: false,
|
||||
|
||||
install ({ $q }) {
|
||||
$q.fullscreen = this
|
||||
}
|
||||
})
|
||||
|
||||
if (__QUASAR_SSR_SERVER__ === true) {
|
||||
assignFn(() => Promise.resolve())
|
||||
}
|
||||
else {
|
||||
prefixes.request = [
|
||||
'requestFullscreen',
|
||||
'msRequestFullscreen', 'mozRequestFullScreen', 'webkitRequestFullscreen'
|
||||
].find(request => document.documentElement[ request ] !== void 0)
|
||||
|
||||
Plugin.isCapable = prefixes.request !== void 0
|
||||
|
||||
if (Plugin.isCapable === false) {
|
||||
// it means the browser does NOT support it
|
||||
assignFn(() => Promise.reject('Not capable'))
|
||||
}
|
||||
else {
|
||||
Object.assign(Plugin, {
|
||||
request (target) {
|
||||
const el = target || document.documentElement
|
||||
const { activeEl } = Plugin
|
||||
|
||||
if (el === activeEl) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
const queue = activeEl !== null && el.contains(activeEl) === true
|
||||
? Plugin.exit()
|
||||
: Promise.resolve()
|
||||
|
||||
return queue.finally(() => promisify(el, prefixes.request))
|
||||
},
|
||||
|
||||
exit () {
|
||||
return Plugin.isActive === true
|
||||
? promisify(document, prefixes.exit)
|
||||
: Promise.resolve()
|
||||
},
|
||||
|
||||
toggle (target) {
|
||||
return Plugin.isActive === true
|
||||
? Plugin.exit()
|
||||
: Plugin.request(target)
|
||||
}
|
||||
})
|
||||
|
||||
prefixes.exit = [
|
||||
'exitFullscreen',
|
||||
'msExitFullscreen', 'mozCancelFullScreen', 'webkitExitFullscreen'
|
||||
].find(exit => document[ exit ])
|
||||
|
||||
Plugin.isActive = Boolean(getFullscreenElement())
|
||||
Plugin.isActive === true && updateEl()
|
||||
|
||||
;[
|
||||
'onfullscreenchange',
|
||||
'onmsfullscreenchange', 'onwebkitfullscreenchange'
|
||||
].forEach(evt => {
|
||||
document[ evt ] = togglePluginState
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Plugin
|
||||
77
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/AppFullscreen.json
generated
vendored
Normal file
77
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/AppFullscreen.json
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/app-fullscreen"
|
||||
},
|
||||
|
||||
"injection": "$q.fullscreen",
|
||||
|
||||
"props": {
|
||||
"isCapable": {
|
||||
"type": "Boolean",
|
||||
"desc": "Does browser support it?"
|
||||
},
|
||||
|
||||
"isActive": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is Fullscreen active?",
|
||||
"reactive": true
|
||||
},
|
||||
|
||||
"activeEl": {
|
||||
"type": [ "Element", "null" ],
|
||||
"desc": "The DOM element used as root for fullscreen, otherwise 'null'",
|
||||
"reactive": true,
|
||||
"examples": [ "document.fullscreenElement", "null" ]
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"request": {
|
||||
"desc": "Request going into Fullscreen (with optional target)",
|
||||
"params": {
|
||||
"target": {
|
||||
"type": "Element",
|
||||
"desc": "Optional Element of target to request Fullscreen on",
|
||||
"examples": [ "document.getElementById('example')" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Promise<void>",
|
||||
"desc": "A Promise which is resolved when transitioned to fullscreen mode. It gets rejected with 'Not capable' if the browser is not capable, and with an Error object if something else went wrong.",
|
||||
"examples": [
|
||||
"request().then(response => { ... }).catch(err => { ... })"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"exit": {
|
||||
"desc": "Request exiting out of Fullscreen mode",
|
||||
"params": null,
|
||||
"returns": {
|
||||
"type": "Promise<void>",
|
||||
"desc": "A Promise which is resolved when exited out of fullscreen mode. It gets rejected with 'Not capable' if the browser is not capable, and with an Error object if something else went wrong.",
|
||||
"examples": [
|
||||
"exit().then(response => { ... }).catch(err => { ... })"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"toggle": {
|
||||
"desc": "Request toggling Fullscreen mode (with optional target if requesting going into Fullscreen only)",
|
||||
"params": {
|
||||
"target": {
|
||||
"type": "Element",
|
||||
"desc": "Optional Element of target to request Fullscreen on",
|
||||
"examples": [ "document.getElementById('example')" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Promise<void>",
|
||||
"desc": "A Promise which is resolved when transitioned to / exited out of fullscreen mode. It gets rejected with 'Not capable' if the browser is not capable, and with an Error object if something else went wrong.",
|
||||
"examples": [
|
||||
"toggle().then(response => { ... }).catch(err => { ... })"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
206
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/AppFullscreen.test.js
generated
vendored
Normal file
206
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/AppFullscreen.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
import { describe, test, expect, afterEach } from 'vitest'
|
||||
import { mount, config } from '@vue/test-utils'
|
||||
|
||||
// jsdom hack
|
||||
// this import should always sit before the AppFullscreen one
|
||||
import { createMockedEl } from './test/mock-fullscreen.js'
|
||||
|
||||
import AppFullscreen from './AppFullscreen.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
// We override Quasar install so it installs this plugin
|
||||
const quasarVuePlugin = config.global.plugins.find(entry => entry.name === 'Quasar')
|
||||
const { install } = quasarVuePlugin
|
||||
quasarVuePlugin.install = app => install(app, { plugins: { AppFullscreen } })
|
||||
|
||||
afterEach(async () => {
|
||||
// ensure we don't leave test in fullscreen state
|
||||
await AppFullscreen.exit()
|
||||
})
|
||||
|
||||
describe('[AppFullscreen API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
expect(AppFullscreen).toMatchObject(wrapper.vm.$q.fullscreen)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)isCapable]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(AppFullscreen.isCapable).toBeTypeOf('boolean')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)isActive]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(AppFullscreen.isActive).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is reactive', async () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(AppFullscreen.isActive).toBe(false)
|
||||
await AppFullscreen.request()
|
||||
expect(AppFullscreen.isActive).toBe(true)
|
||||
|
||||
await AppFullscreen.exit()
|
||||
expect(AppFullscreen.isActive).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)activeEl]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(AppFullscreen.activeEl).$any([
|
||||
expect.any(Element),
|
||||
null
|
||||
])
|
||||
})
|
||||
|
||||
test('is reactive', async () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
await AppFullscreen.request()
|
||||
expect(AppFullscreen.activeEl).not.toBe(null)
|
||||
|
||||
await AppFullscreen.exit()
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)request]', () => {
|
||||
test('request()', async () => {
|
||||
mountPlugin()
|
||||
|
||||
const result = AppFullscreen.request()
|
||||
expect(
|
||||
result
|
||||
).toBeInstanceOf(Promise)
|
||||
|
||||
await result
|
||||
expect(AppFullscreen.isActive).toBe(true)
|
||||
expect(AppFullscreen.activeEl).not.toBe(null)
|
||||
|
||||
await AppFullscreen.exit()
|
||||
expect(AppFullscreen.isActive).toBe(false)
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
})
|
||||
|
||||
test('request(el)', async () => {
|
||||
mountPlugin()
|
||||
|
||||
const el = createMockedEl()
|
||||
|
||||
const result = AppFullscreen.request(el)
|
||||
expect(
|
||||
result
|
||||
).toBeInstanceOf(Promise)
|
||||
|
||||
await result
|
||||
|
||||
expect(el.requestFullscreen).toHaveBeenCalledTimes(1)
|
||||
expect(AppFullscreen.isActive).toBe(true)
|
||||
expect(AppFullscreen.activeEl).toBe(el)
|
||||
|
||||
await AppFullscreen.exit()
|
||||
expect(AppFullscreen.isActive).toBe(false)
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
})
|
||||
|
||||
test('call request(el) 2 times', async () => {
|
||||
mountPlugin()
|
||||
|
||||
const el = createMockedEl()
|
||||
|
||||
const result = AppFullscreen.request(el)
|
||||
expect(
|
||||
result
|
||||
).toBeInstanceOf(Promise)
|
||||
|
||||
await result
|
||||
expect(el.requestFullscreen).toHaveBeenCalledTimes(1)
|
||||
expect(AppFullscreen.activeEl).toBe(el)
|
||||
|
||||
await AppFullscreen.request(el)
|
||||
expect(el.requestFullscreen).toHaveBeenCalledTimes(1)
|
||||
expect(AppFullscreen.activeEl).toBe(el)
|
||||
|
||||
await AppFullscreen.exit()
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)exit]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
expect(
|
||||
AppFullscreen.exit()
|
||||
).toBeInstanceOf(Promise)
|
||||
})
|
||||
|
||||
test('request() + exit()', async () => {
|
||||
mountPlugin()
|
||||
|
||||
const result = AppFullscreen.request()
|
||||
expect(
|
||||
result
|
||||
).toBeInstanceOf(Promise)
|
||||
|
||||
await result
|
||||
expect(AppFullscreen.isActive).toBe(true)
|
||||
expect(AppFullscreen.activeEl).not.toBe(null)
|
||||
|
||||
await AppFullscreen.exit()
|
||||
expect(AppFullscreen.isActive).toBe(false)
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)toggle]', () => {
|
||||
test('toggle()', async () => {
|
||||
mountPlugin()
|
||||
|
||||
const result = AppFullscreen.toggle()
|
||||
expect(
|
||||
result
|
||||
).toBeInstanceOf(Promise)
|
||||
|
||||
await result
|
||||
expect(AppFullscreen.isActive).toBe(true)
|
||||
expect(AppFullscreen.activeEl).not.toBe(null)
|
||||
|
||||
await AppFullscreen.toggle()
|
||||
expect(AppFullscreen.isActive).toBe(false)
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
})
|
||||
|
||||
test('toggle(el)', async () => {
|
||||
mountPlugin()
|
||||
|
||||
const el = createMockedEl()
|
||||
|
||||
const result = AppFullscreen.toggle(el)
|
||||
expect(
|
||||
result
|
||||
).toBeInstanceOf(Promise)
|
||||
|
||||
await result
|
||||
expect(el.requestFullscreen).toHaveBeenCalledTimes(1)
|
||||
expect(AppFullscreen.isActive).toBe(true)
|
||||
expect(AppFullscreen.activeEl).toBe(el)
|
||||
|
||||
await AppFullscreen.toggle()
|
||||
expect(AppFullscreen.isActive).toBe(false)
|
||||
expect(AppFullscreen.activeEl).toBe(null)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
43
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/test/mock-fullscreen.js
generated
vendored
Normal file
43
Frontend-Learner/node_modules/quasar/src/plugins/app-fullscreen/test/mock-fullscreen.js
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { vi, onTestFinished } from 'vitest'
|
||||
|
||||
/**
|
||||
* jsdom does not support Fullscreen API,
|
||||
* so we mock the functionality
|
||||
*/
|
||||
|
||||
export function mockedRequestFullscreen (el = document.documentElement) {
|
||||
document.fullscreenElement = el
|
||||
mockedToggleFullscreen()
|
||||
}
|
||||
|
||||
export function mockedExitFullscreen () {
|
||||
document.fullscreenElement = null
|
||||
mockedToggleFullscreen()
|
||||
}
|
||||
|
||||
export function mockedToggleFullscreen () {
|
||||
document.onfullscreenchange()
|
||||
}
|
||||
|
||||
export function createMockedEl () {
|
||||
const el = document.createElement('div')
|
||||
el.setAttribute('tabindex', '0')
|
||||
document.body.appendChild(el)
|
||||
|
||||
el.requestFullscreen = vi.fn(() => {
|
||||
document.fullscreenElement = el
|
||||
mockedToggleFullscreen()
|
||||
})
|
||||
|
||||
el.exitFullscreen = mockedExitFullscreen
|
||||
|
||||
onTestFinished(() => { el.remove() })
|
||||
|
||||
return el
|
||||
}
|
||||
|
||||
document.documentElement.requestFullscreen = mockedRequestFullscreen
|
||||
document.documentElement.exitFullscreen = mockedExitFullscreen
|
||||
|
||||
document.requestFullscreen = mockedRequestFullscreen
|
||||
document.exitFullscreen = mockedExitFullscreen
|
||||
39
Frontend-Learner/node_modules/quasar/src/plugins/app-visibility/AppVisibility.js
generated
vendored
Normal file
39
Frontend-Learner/node_modules/quasar/src/plugins/app-visibility/AppVisibility.js
generated
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
import { injectProp } from '../../utils/private.inject-obj-prop/inject-obj-prop.js'
|
||||
|
||||
const Plugin = createReactivePlugin({
|
||||
appVisible: true
|
||||
}, {
|
||||
install ({ $q }) {
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
this.appVisible = $q.appVisible = true
|
||||
return
|
||||
}
|
||||
|
||||
injectProp($q, 'appVisible', () => this.appVisible)
|
||||
}
|
||||
})
|
||||
|
||||
if (__QUASAR_SSR_SERVER__ !== true) {
|
||||
let prop, evt
|
||||
|
||||
if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
|
||||
prop = 'hidden'
|
||||
evt = 'visibilitychange'
|
||||
}
|
||||
else if (typeof document.msHidden !== 'undefined') {
|
||||
prop = 'msHidden'
|
||||
evt = 'msvisibilitychange'
|
||||
}
|
||||
else if (typeof document.webkitHidden !== 'undefined') {
|
||||
prop = 'webkitHidden'
|
||||
evt = 'webkitvisibilitychange'
|
||||
}
|
||||
|
||||
if (evt && typeof document[ prop ] !== 'undefined') {
|
||||
const update = () => { Plugin.appVisible = !document[ prop ] }
|
||||
document.addEventListener(evt, update, false)
|
||||
}
|
||||
}
|
||||
|
||||
export default Plugin
|
||||
16
Frontend-Learner/node_modules/quasar/src/plugins/app-visibility/AppVisibility.json
generated
vendored
Normal file
16
Frontend-Learner/node_modules/quasar/src/plugins/app-visibility/AppVisibility.json
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/app-visibility"
|
||||
},
|
||||
|
||||
"injection": "$q.appVisible",
|
||||
|
||||
"props": {
|
||||
"appVisible": {
|
||||
"tsInjectionPoint": true,
|
||||
"type": "Boolean",
|
||||
"desc": "Does the app have user focus? Or the app runs in the background / another tab has the user's attention",
|
||||
"reactive": true
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Frontend-Learner/node_modules/quasar/src/plugins/app-visibility/AppVisibility.test.js
generated
vendored
Normal file
45
Frontend-Learner/node_modules/quasar/src/plugins/app-visibility/AppVisibility.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
import { mount, config } from '@vue/test-utils'
|
||||
|
||||
import AppVisibility from './AppVisibility.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
// We override Quasar install so it installs this plugin
|
||||
const quasarVuePlugin = config.global.plugins.find(entry => entry.name === 'Quasar')
|
||||
const { install } = quasarVuePlugin
|
||||
quasarVuePlugin.install = app => install(app, { plugins: { AppVisibility } })
|
||||
|
||||
describe('[AppVisibility API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
expect(wrapper.vm.$q.appVisible).toBe(AppVisibility.appVisible)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)appVisible]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(AppVisibility.appVisible).toBe(true)
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
const wrapper = mountPlugin()
|
||||
expect(AppVisibility.appVisible).toBe(true)
|
||||
|
||||
// jsdom hack
|
||||
Object.defineProperty(document, 'hidden', {
|
||||
configurable: true,
|
||||
get: () => true
|
||||
})
|
||||
|
||||
document.dispatchEvent(new Event('visibilitychange'))
|
||||
|
||||
expect(AppVisibility.appVisible).toBe(false)
|
||||
expect(wrapper.vm.$q.appVisible).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
8
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/BottomSheet.js
generated
vendored
Normal file
8
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/BottomSheet.js
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import BottomSheet from './component/BottomSheetComponent.js'
|
||||
import globalDialog from '../../utils/private.dialog/create-dialog.js'
|
||||
|
||||
export default {
|
||||
install ({ $q, parentApp }) {
|
||||
$q.bottomSheet = this.create = globalDialog(BottomSheet, false, parentApp)
|
||||
}
|
||||
}
|
||||
110
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/BottomSheet.json
generated
vendored
Normal file
110
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/BottomSheet.json
generated
vendored
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"mixins": [ "utils/private.dialog/create-dialog" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/bottom-sheet"
|
||||
},
|
||||
|
||||
"injection": "$q.bottomSheet",
|
||||
|
||||
"methods": {
|
||||
"create": {
|
||||
"tsInjectionPoint": true,
|
||||
"desc": "Creates an ad-hoc Bottom Sheet; Same as calling $q.bottomSheet(...)",
|
||||
"params": {
|
||||
"opts": {
|
||||
"desc": "Bottom Sheet options",
|
||||
"definition": {
|
||||
"title": {
|
||||
"type": "String",
|
||||
"desc": "Title",
|
||||
"examples": [ "'Share'" ]
|
||||
},
|
||||
|
||||
"message": {
|
||||
"type": "String",
|
||||
"desc": "Message",
|
||||
"examples": [ "'Please select how to share'" ]
|
||||
},
|
||||
|
||||
"actions": {
|
||||
"type": "Array",
|
||||
"desc": "Array of Objects, each Object defining an action",
|
||||
"definition": {
|
||||
"classes": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueClassProp",
|
||||
"desc": "CSS classes for this action",
|
||||
"examples": [ "'my-class'" ]
|
||||
},
|
||||
|
||||
"style": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueStyleProp",
|
||||
"desc": "Style definitions to be attributed to this action element",
|
||||
"examples": [ "{ padding: '2px' }" ],
|
||||
"addedIn": "v2.11.7"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"img": {
|
||||
"type": "String",
|
||||
"desc": "Path to an image for this action",
|
||||
"examples": [
|
||||
"# (public folder) 'img/something.png'",
|
||||
"# (relative path format) :src=\"require('./my_img.jpg')\"",
|
||||
"# (URL) https://some-site.net/some-img.gif"
|
||||
]
|
||||
},
|
||||
|
||||
"avatar": {
|
||||
"type": "String",
|
||||
"desc": "Path to an avatar image for this action",
|
||||
"examples": [
|
||||
"# (public folder) 'img/avatar.png'",
|
||||
"# (relative path format) :src=\"require('./my_img.jpg')\"",
|
||||
"# (URL) https://some-site.net/some-img.gif"
|
||||
]
|
||||
},
|
||||
|
||||
"label": {
|
||||
"type": [ "String", "Number" ],
|
||||
"desc": "Action label",
|
||||
"examples": [ "'Facebook'" ]
|
||||
},
|
||||
|
||||
"...": {
|
||||
"type": "Any",
|
||||
"desc": "Any other custom props"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"grid": {
|
||||
"type": "Boolean",
|
||||
"desc": "Display actions as a grid instead of as a list"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"extends": "dark",
|
||||
"desc": "Apply dark mode"
|
||||
},
|
||||
|
||||
"seamless": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put Bottom Sheet into seamless mode; Does not use a backdrop so user is able to interact with the rest of the page too"
|
||||
},
|
||||
|
||||
"persistent": {
|
||||
"type": "Boolean",
|
||||
"desc": "User cannot dismiss Bottom Sheet if clicking outside of it or hitting ESC key; Also, an app route change won't dismiss it"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
183
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/component/BottomSheetComponent.js
generated
vendored
Normal file
183
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/component/BottomSheetComponent.js
generated
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
import { h, ref, getCurrentInstance } from 'vue'
|
||||
|
||||
import QDialog from '../../../components/dialog/QDialog.js'
|
||||
|
||||
import QIcon from '../../../components/icon/QIcon.js'
|
||||
import QSeparator from '../../../components/separator/QSeparator.js'
|
||||
|
||||
import QCard from '../../../components/card/QCard.js'
|
||||
import QCardSection from '../../../components/card/QCardSection.js'
|
||||
|
||||
import QItem from '../../../components/item/QItem.js'
|
||||
import QItemSection from '../../../components/item/QItemSection.js'
|
||||
|
||||
import { createComponent } from '../../../utils/private.create/create.js'
|
||||
import useDark, { useDarkProps } from '../../../composables/private.use-dark/use-dark.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'BottomSheetComponent',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
|
||||
title: String,
|
||||
message: String,
|
||||
actions: Array,
|
||||
|
||||
grid: Boolean,
|
||||
|
||||
cardClass: [ String, Array, Object ],
|
||||
cardStyle: [ String, Array, Object ]
|
||||
},
|
||||
|
||||
emits: [ 'ok', 'hide' ],
|
||||
|
||||
setup (props, { emit }) {
|
||||
const { proxy } = getCurrentInstance()
|
||||
const isDark = useDark(props, proxy.$q)
|
||||
|
||||
const dialogRef = ref(null)
|
||||
|
||||
function show () {
|
||||
dialogRef.value.show()
|
||||
}
|
||||
|
||||
function hide () {
|
||||
dialogRef.value.hide()
|
||||
}
|
||||
|
||||
function onOk (action) {
|
||||
emit('ok', action)
|
||||
hide()
|
||||
}
|
||||
|
||||
function onHide () {
|
||||
emit('hide')
|
||||
}
|
||||
|
||||
function getGrid () {
|
||||
return props.actions.map(action => {
|
||||
const img = action.avatar || action.img
|
||||
|
||||
return action.label === void 0
|
||||
? h(QSeparator, {
|
||||
class: 'col-all',
|
||||
dark: isDark.value
|
||||
})
|
||||
: h('div', {
|
||||
class: [
|
||||
'q-bottom-sheet__item q-hoverable q-focusable cursor-pointer relative-position',
|
||||
action.class
|
||||
],
|
||||
style: action.style,
|
||||
tabindex: 0,
|
||||
role: 'listitem',
|
||||
onClick () { onOk(action) },
|
||||
onKeyup (e) { e.keyCode === 13 && onOk(action) }
|
||||
}, [
|
||||
h('div', { class: 'q-focus-helper' }),
|
||||
|
||||
action.icon
|
||||
? h(QIcon, { name: action.icon, color: action.color })
|
||||
: (
|
||||
img
|
||||
? h('img', {
|
||||
class: action.avatar ? 'q-bottom-sheet__avatar' : '',
|
||||
src: img
|
||||
})
|
||||
: h('div', { class: 'q-bottom-sheet__empty-icon' })
|
||||
),
|
||||
|
||||
h('div', action.label)
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
function getList () {
|
||||
return props.actions.map(action => {
|
||||
const img = action.avatar || action.img
|
||||
|
||||
return action.label === void 0
|
||||
? h(QSeparator, { spaced: true, dark: isDark.value })
|
||||
: h(QItem, {
|
||||
class: [ 'q-bottom-sheet__item', action.classes ],
|
||||
style: action.style,
|
||||
tabindex: 0,
|
||||
clickable: true,
|
||||
dark: isDark.value,
|
||||
onClick () { onOk(action) }
|
||||
}, () => [
|
||||
h(
|
||||
QItemSection,
|
||||
{ avatar: true },
|
||||
() => (
|
||||
action.icon
|
||||
? h(QIcon, { name: action.icon, color: action.color })
|
||||
: (
|
||||
img
|
||||
? h('img', {
|
||||
class: action.avatar ? 'q-bottom-sheet__avatar' : '',
|
||||
src: img
|
||||
})
|
||||
: null
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
h(QItemSection, () => action.label)
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
function getCardContent () {
|
||||
const child = []
|
||||
|
||||
props.title && child.push(
|
||||
h(QCardSection, {
|
||||
class: 'q-dialog__title'
|
||||
}, () => props.title)
|
||||
)
|
||||
|
||||
props.message && child.push(
|
||||
h(QCardSection, {
|
||||
class: 'q-dialog__message'
|
||||
}, () => props.message)
|
||||
)
|
||||
|
||||
child.push(
|
||||
props.grid === true
|
||||
? h('div', {
|
||||
class: 'row items-stretch justify-start',
|
||||
role: 'list'
|
||||
}, getGrid())
|
||||
: h('div', {
|
||||
role: 'list'
|
||||
}, getList())
|
||||
)
|
||||
|
||||
return child
|
||||
}
|
||||
|
||||
function getContent () {
|
||||
return [
|
||||
h(QCard, {
|
||||
class: [
|
||||
`q-bottom-sheet q-bottom-sheet--${ props.grid === true ? 'grid' : 'list' }`
|
||||
+ (isDark.value === true ? ' q-bottom-sheet--dark q-dark' : ''),
|
||||
props.cardClass
|
||||
],
|
||||
style: props.cardStyle
|
||||
}, getCardContent)
|
||||
]
|
||||
}
|
||||
|
||||
// expose public methods
|
||||
Object.assign(proxy, { show, hide })
|
||||
|
||||
return () => h(QDialog, {
|
||||
ref: dialogRef,
|
||||
position: 'bottom',
|
||||
onHide
|
||||
}, getContent)
|
||||
}
|
||||
})
|
||||
37
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/component/BottomSheetComponent.sass
generated
vendored
Normal file
37
Frontend-Learner/node_modules/quasar/src/plugins/bottom-sheet/component/BottomSheetComponent.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
.q-bottom-sheet
|
||||
padding-bottom: 8px
|
||||
|
||||
&__avatar
|
||||
border-radius: 50%
|
||||
|
||||
&--list
|
||||
width: 400px
|
||||
|
||||
.q-icon, img
|
||||
font-size: 24px
|
||||
width: 24px
|
||||
height: 24px
|
||||
|
||||
&--grid
|
||||
width: 700px
|
||||
|
||||
.q-bottom-sheet__item
|
||||
padding: 8px
|
||||
text-align: center
|
||||
min-width: 100px
|
||||
|
||||
.q-icon, img, .q-bottom-sheet__empty-icon
|
||||
font-size: 48px
|
||||
width: 48px
|
||||
height: 48px
|
||||
margin-bottom: 8px
|
||||
|
||||
.q-separator
|
||||
margin: 12px 0
|
||||
|
||||
&__item
|
||||
flex: 0 0 33.3333%
|
||||
|
||||
@media (min-width: $breakpoint-sm-min)
|
||||
.q-bottom-sheet__item
|
||||
flex: 0 0 25%
|
||||
208
Frontend-Learner/node_modules/quasar/src/plugins/cookies/Cookies.js
generated
vendored
Normal file
208
Frontend-Learner/node_modules/quasar/src/plugins/cookies/Cookies.js
generated
vendored
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
function encode (string) {
|
||||
return encodeURIComponent(string)
|
||||
}
|
||||
|
||||
function decode (string) {
|
||||
return decodeURIComponent(string)
|
||||
}
|
||||
|
||||
function stringifyCookieValue (value) {
|
||||
return encode(value === Object(value) ? JSON.stringify(value) : '' + value)
|
||||
}
|
||||
|
||||
function read (string) {
|
||||
if (string === '') {
|
||||
return string
|
||||
}
|
||||
|
||||
if (string.indexOf('"') === 0) {
|
||||
// This is a quoted cookie as according to RFC2068, unescape...
|
||||
string = string.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\')
|
||||
}
|
||||
|
||||
// Replace server-side written pluses with spaces.
|
||||
// If we can't decode the cookie, ignore it, it's unusable.
|
||||
// If we can't parse the cookie, ignore it, it's unusable.
|
||||
string = decode(string.replace(/\+/g, ' '))
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(string)
|
||||
|
||||
if (parsed === Object(parsed) || Array.isArray(parsed) === true) {
|
||||
string = parsed
|
||||
}
|
||||
}
|
||||
catch (_) {}
|
||||
|
||||
return string
|
||||
}
|
||||
|
||||
function getString (msOffset) {
|
||||
const time = new Date()
|
||||
time.setMilliseconds(time.getMilliseconds() + msOffset)
|
||||
return time.toUTCString()
|
||||
}
|
||||
|
||||
function parseExpireString (str) {
|
||||
let timestamp = 0
|
||||
|
||||
const days = str.match(/(\d+)d/)
|
||||
const hours = str.match(/(\d+)h/)
|
||||
const minutes = str.match(/(\d+)m/)
|
||||
const seconds = str.match(/(\d+)s/)
|
||||
|
||||
if (days) { timestamp += days[ 1 ] * 864e+5 }
|
||||
if (hours) { timestamp += hours[ 1 ] * 36e+5 }
|
||||
if (minutes) { timestamp += minutes[ 1 ] * 6e+4 }
|
||||
if (seconds) { timestamp += seconds[ 1 ] * 1000 }
|
||||
|
||||
return timestamp === 0
|
||||
? str
|
||||
: getString(timestamp)
|
||||
}
|
||||
|
||||
function set (key, val, opts = {}, ssr) {
|
||||
let expire, expireValue
|
||||
|
||||
if (opts.expires !== void 0) {
|
||||
// if it's a Date Object
|
||||
if (Object.prototype.toString.call(opts.expires) === '[object Date]') {
|
||||
expire = opts.expires.toUTCString()
|
||||
}
|
||||
// if it's a String (eg. "15m", "1h", "13d", "1d 15m", "31s")
|
||||
// possible units: d (days), h (hours), m (minutes), s (seconds)
|
||||
else if (typeof opts.expires === 'string') {
|
||||
expire = parseExpireString(opts.expires)
|
||||
}
|
||||
// otherwise it must be a Number (defined in days)
|
||||
else {
|
||||
expireValue = parseFloat(opts.expires)
|
||||
expire = isNaN(expireValue) === false
|
||||
? getString(expireValue * 864e+5)
|
||||
: opts.expires
|
||||
}
|
||||
}
|
||||
|
||||
const keyValue = `${ encode(key) }=${ stringifyCookieValue(val) }`
|
||||
|
||||
const cookie = [
|
||||
keyValue,
|
||||
expire !== void 0 ? '; Expires=' + expire : '', // use expires attribute, max-age is not supported by IE
|
||||
opts.path ? '; Path=' + opts.path : '',
|
||||
opts.domain ? '; Domain=' + opts.domain : '',
|
||||
opts.sameSite ? '; SameSite=' + opts.sameSite : '',
|
||||
opts.httpOnly ? '; HttpOnly' : '',
|
||||
opts.secure ? '; Secure' : '',
|
||||
opts.other ? '; ' + opts.other : ''
|
||||
].join('')
|
||||
|
||||
if (ssr) {
|
||||
if (ssr.req.qCookies) {
|
||||
ssr.req.qCookies.push(cookie)
|
||||
}
|
||||
else {
|
||||
ssr.req.qCookies = [ cookie ]
|
||||
}
|
||||
|
||||
ssr.res.setHeader('Set-Cookie', ssr.req.qCookies)
|
||||
|
||||
// make temporary update so future get()
|
||||
// within same SSR timeframe would return the set value
|
||||
|
||||
let all = ssr.req.headers.cookie || ''
|
||||
|
||||
if (expire !== void 0 && expireValue < 0) {
|
||||
const val = get(key, ssr)
|
||||
if (val !== undefined) {
|
||||
all = all
|
||||
.replace(`${ key }=${ val }; `, '')
|
||||
.replace(`; ${ key }=${ val }`, '')
|
||||
.replace(`${ key }=${ val }`, '')
|
||||
}
|
||||
}
|
||||
else {
|
||||
all = all
|
||||
? `${ keyValue }; ${ all }`
|
||||
: cookie
|
||||
}
|
||||
|
||||
ssr.req.headers.cookie = all
|
||||
}
|
||||
else {
|
||||
document.cookie = cookie
|
||||
}
|
||||
}
|
||||
|
||||
function get (key, ssr) {
|
||||
const
|
||||
cookieSource = ssr ? ssr.req.headers : document,
|
||||
cookies = cookieSource.cookie ? cookieSource.cookie.split('; ') : [],
|
||||
l = cookies.length
|
||||
let
|
||||
result = key ? null : {},
|
||||
i = 0,
|
||||
parts,
|
||||
name,
|
||||
cookie
|
||||
|
||||
for (; i < l; i++) {
|
||||
parts = cookies[ i ].split('=')
|
||||
name = decode(parts.shift())
|
||||
cookie = parts.join('=')
|
||||
|
||||
if (!key) {
|
||||
result[ name ] = cookie
|
||||
}
|
||||
else if (key === name) {
|
||||
result = read(cookie)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function remove (key, options, ssr) {
|
||||
set(
|
||||
key,
|
||||
'',
|
||||
{ expires: -1, ...options },
|
||||
ssr
|
||||
)
|
||||
}
|
||||
|
||||
function has (key, ssr) {
|
||||
return get(key, ssr) !== null
|
||||
}
|
||||
|
||||
export function getObject (ssr) {
|
||||
return {
|
||||
get: key => get(key, ssr),
|
||||
set: (key, val, opts) => set(key, val, opts, ssr),
|
||||
has: key => has(key, ssr),
|
||||
remove: (key, options) => remove(key, options, ssr),
|
||||
getAll: () => get(null, ssr)
|
||||
}
|
||||
}
|
||||
|
||||
const Plugin = {
|
||||
install ({ $q, ssrContext }) {
|
||||
$q.cookies = __QUASAR_SSR_SERVER__
|
||||
? getObject(ssrContext)
|
||||
: this
|
||||
}
|
||||
}
|
||||
|
||||
if (__QUASAR_SSR__) {
|
||||
Plugin.parseSSR = ssrContext => {
|
||||
if (ssrContext !== void 0) {
|
||||
return getObject(ssrContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (__QUASAR_SSR_SERVER__ !== true) {
|
||||
Object.assign(Plugin, getObject())
|
||||
}
|
||||
|
||||
export default Plugin
|
||||
159
Frontend-Learner/node_modules/quasar/src/plugins/cookies/Cookies.json
generated
vendored
Normal file
159
Frontend-Learner/node_modules/quasar/src/plugins/cookies/Cookies.json
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/cookies"
|
||||
},
|
||||
|
||||
"injection": "$q.cookies",
|
||||
|
||||
"methods": {
|
||||
"get": {
|
||||
"tsType": "CookiesGetMethodType",
|
||||
"desc": "Get cookie",
|
||||
"params": {
|
||||
"name": {
|
||||
"type": "String",
|
||||
"desc": "Cookie name",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": [ "String", "null" ],
|
||||
"desc": "Cookie value; Returns null if cookie not found",
|
||||
"examples": [ "'john12'" ]
|
||||
}
|
||||
},
|
||||
|
||||
"getAll": {
|
||||
"desc": "Get all cookies",
|
||||
"params": null,
|
||||
"returns": {
|
||||
"type": "Object",
|
||||
"desc": "Object with cookie names (as keys) and their values",
|
||||
"examples": [ "{ userId: 'john12', XFrame: 'x534' }" ]
|
||||
}
|
||||
},
|
||||
|
||||
"set": {
|
||||
"desc": "Set cookie",
|
||||
"params": {
|
||||
"name": {
|
||||
"type": "String",
|
||||
"desc": "Cookie name",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
},
|
||||
|
||||
"value": {
|
||||
"type": "String",
|
||||
"desc": "Cookie value",
|
||||
"required": true,
|
||||
"examples": [ "'john12'" ]
|
||||
},
|
||||
|
||||
"options": {
|
||||
"type": "Object",
|
||||
"desc": "Cookie options",
|
||||
"definition": {
|
||||
"expires": {
|
||||
"type": [ "Number", "String", "Date" ],
|
||||
"desc": "Cookie expires detail; If specified as Number, then the unit is days; If specified as String, it can either be raw stringified date or in Xd Xh Xm Xs format (see examples)",
|
||||
"examples": [ "30", "'Wed, 13 Jan 2021 22:23:01 GMT'", "'1d'", "'15m'", "'13d'", "'1d 15m'", "'1d 3h 5m 3s'" ]
|
||||
},
|
||||
"path": {
|
||||
"type": "String",
|
||||
"desc": "Cookie path",
|
||||
"examples": [ "'/accounts'" ]
|
||||
},
|
||||
"domain": {
|
||||
"type": "String",
|
||||
"desc": "Cookie domain",
|
||||
"examples": [ "'.foo.com'" ]
|
||||
},
|
||||
"sameSite": {
|
||||
"type": "String",
|
||||
"desc": "SameSite cookie option",
|
||||
"values": [ "'Lax'", "'Strict'", "'None'" ]
|
||||
},
|
||||
"httpOnly": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is cookie Http Only?"
|
||||
},
|
||||
"secure": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is cookie secure? (https only)"
|
||||
},
|
||||
"other": {
|
||||
"type": "String",
|
||||
"desc": "Raw string for other cookie options; To be used as a last resort for possible newer props that are currently not yet implemented in Quasar",
|
||||
"examples": [ "'SomeNewCookieProp'" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"has": {
|
||||
"desc": "Check if cookie exists",
|
||||
"params": {
|
||||
"name": {
|
||||
"type": "String",
|
||||
"desc": "Cookie name",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "Does cookie exists or not?"
|
||||
}
|
||||
},
|
||||
|
||||
"remove": {
|
||||
"desc": "Remove a cookie",
|
||||
"params": {
|
||||
"name": {
|
||||
"type": "String",
|
||||
"desc": "Cookie name",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
},
|
||||
|
||||
"options": {
|
||||
"type": "Object",
|
||||
"desc": "Cookie options",
|
||||
"definition": {
|
||||
"path": {
|
||||
"type": "String",
|
||||
"desc": "Cookie path",
|
||||
"examples": [ "'/accounts'" ]
|
||||
},
|
||||
"domain": {
|
||||
"type": "String",
|
||||
"desc": "Cookie domain",
|
||||
"examples": [ "'.foo.com'" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"parseSSR": {
|
||||
"desc": "For SSR usage only, and only on the global import (not on $q.cookies)",
|
||||
"params": {
|
||||
"ssrContext": {
|
||||
"type": "Object",
|
||||
"desc": "SSR Context Object",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Object",
|
||||
"tsType": "Cookies",
|
||||
"desc": "Cookie object (like $q.cookies) for SSR usage purposes"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Frontend-Learner/node_modules/quasar/src/plugins/dark/Dark.js
generated
vendored
Normal file
75
Frontend-Learner/node_modules/quasar/src/plugins/dark/Dark.js
generated
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
|
||||
const Plugin = createReactivePlugin({
|
||||
isActive: false,
|
||||
mode: false
|
||||
}, {
|
||||
__media: void 0,
|
||||
|
||||
set (val) {
|
||||
if (__QUASAR_SSR_SERVER__) return
|
||||
|
||||
Plugin.mode = val
|
||||
|
||||
if (val === 'auto') {
|
||||
if (Plugin.__media === void 0) {
|
||||
Plugin.__media = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
Plugin.__updateMedia = () => { Plugin.set('auto') }
|
||||
Plugin.__media.addListener(Plugin.__updateMedia)
|
||||
}
|
||||
|
||||
val = Plugin.__media.matches
|
||||
}
|
||||
else if (Plugin.__media !== void 0) {
|
||||
Plugin.__media.removeListener(Plugin.__updateMedia)
|
||||
Plugin.__media = void 0
|
||||
}
|
||||
|
||||
Plugin.isActive = val === true
|
||||
document.body.classList.remove(`body--${ val === true ? 'light' : 'dark' }`)
|
||||
document.body.classList.add(`body--${ val === true ? 'dark' : 'light' }`)
|
||||
},
|
||||
|
||||
toggle () {
|
||||
if (__QUASAR_SSR_SERVER__ !== true) {
|
||||
Plugin.set(Plugin.isActive === false)
|
||||
}
|
||||
},
|
||||
|
||||
install ({ $q, ssrContext }) {
|
||||
const dark = __QUASAR_SSR_CLIENT__
|
||||
? document.body.classList.contains('body--dark')
|
||||
: $q.config.dark
|
||||
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
this.isActive = dark === true
|
||||
|
||||
$q.dark = {
|
||||
isActive: false,
|
||||
mode: false,
|
||||
set: val => {
|
||||
ssrContext._meta.bodyClasses = ssrContext._meta.bodyClasses
|
||||
.replace(' body--light', '')
|
||||
.replace(' body--dark', '') + ` body--${ val === true ? 'dark' : 'light' }`
|
||||
|
||||
$q.dark.isActive = val === true
|
||||
$q.dark.mode = val
|
||||
},
|
||||
toggle: () => {
|
||||
$q.dark.set($q.dark.isActive === false)
|
||||
}
|
||||
}
|
||||
|
||||
$q.dark.set(dark)
|
||||
return
|
||||
}
|
||||
|
||||
$q.dark = this
|
||||
|
||||
if (this.__installed !== true) {
|
||||
this.set(dark !== void 0 ? dark : false)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default Plugin
|
||||
50
Frontend-Learner/node_modules/quasar/src/plugins/dark/Dark.json
generated
vendored
Normal file
50
Frontend-Learner/node_modules/quasar/src/plugins/dark/Dark.json
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/dark"
|
||||
},
|
||||
|
||||
"injection": "$q.dark",
|
||||
|
||||
"quasarConfOptions": {
|
||||
"propName": "dark",
|
||||
"type": [ "Boolean", "String" ],
|
||||
"desc": "\"'auto'\" uses the OS/browser preference. \"true\" forces dark mode. \"false\" forces light mode.",
|
||||
"values": [ "'auto'", "true", "false" ]
|
||||
},
|
||||
|
||||
"props": {
|
||||
"isActive": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is Dark mode active?",
|
||||
"reactive": true
|
||||
},
|
||||
|
||||
"mode": {
|
||||
"type": [ "Boolean", "String" ],
|
||||
"desc": "Dark mode configuration (not status)",
|
||||
"values": [ "'auto'", "true", "false" ],
|
||||
"reactive": true
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"set": {
|
||||
"desc": "Set dark mode status",
|
||||
"params": {
|
||||
"status": {
|
||||
"type": [ "Boolean", "String" ],
|
||||
"desc": "Dark mode status",
|
||||
"values": [ "true", "false", "'auto'" ],
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"toggle": {
|
||||
"desc": "Toggle dark mode status",
|
||||
"params": null,
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
158
Frontend-Learner/node_modules/quasar/src/plugins/dark/Dark.test.js
generated
vendored
Normal file
158
Frontend-Learner/node_modules/quasar/src/plugins/dark/Dark.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
import { describe, test, expect, vi } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import Dark from './Dark.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
describe('[Dark API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
expect(Dark).toMatchObject(wrapper.vm.$q.dark)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)isActive]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Dark.isActive).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
|
||||
expect(Dark.isActive).toBe(false)
|
||||
expect($q.dark.isActive).toBe(false)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(false)
|
||||
|
||||
Dark.set(true)
|
||||
|
||||
expect(Dark.isActive).toBe(true)
|
||||
expect($q.dark.isActive).toBe(true)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)mode]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect([ 'auto', true, false ]).toContain(Dark.mode)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)set]', () => {
|
||||
test('should be callable', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
|
||||
expect(
|
||||
Dark.set(true)
|
||||
).toBeUndefined()
|
||||
|
||||
expect(Dark.isActive).toBe(true)
|
||||
expect($q.dark.isActive).toBe(true)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(true)
|
||||
|
||||
expect(
|
||||
Dark.set(false)
|
||||
).toBeUndefined()
|
||||
|
||||
expect(Dark.isActive).toBe(false)
|
||||
expect($q.dark.isActive).toBe(false)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
test('should handle auto mode', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
|
||||
// jsdom hack
|
||||
const media = {
|
||||
matches: true,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn()
|
||||
}
|
||||
window.matchMedia = vi.fn(() => media)
|
||||
|
||||
Dark.set('auto')
|
||||
|
||||
expect(Dark.mode).toBe('auto')
|
||||
|
||||
expect(media.addListener).toHaveBeenCalledTimes(1)
|
||||
expect(media.removeListener).not.toHaveBeenCalled()
|
||||
|
||||
expect(Dark.isActive).toBe(true)
|
||||
expect($q.dark.isActive).toBe(true)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(true)
|
||||
|
||||
media.matches = false
|
||||
Dark.__updateMedia()
|
||||
|
||||
expect(media.addListener).toHaveBeenCalledTimes(1)
|
||||
expect(media.removeListener).not.toHaveBeenCalled()
|
||||
|
||||
expect(Dark.isActive).toBe(false)
|
||||
expect($q.dark.isActive).toBe(false)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(false)
|
||||
|
||||
Dark.set(true)
|
||||
expect(Dark.mode).not.toBe('auto')
|
||||
|
||||
expect(media.addListener).toHaveBeenCalledTimes(1)
|
||||
expect(media.removeListener).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(Dark.isActive).toBe(true)
|
||||
expect($q.dark.isActive).toBe(true)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)toggle]', () => {
|
||||
test('should be callable', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
|
||||
Dark.set(true)
|
||||
|
||||
expect(Dark.isActive).toBe(true)
|
||||
expect($q.dark.isActive).toBe(true)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(true)
|
||||
|
||||
expect(
|
||||
Dark.toggle()
|
||||
).toBeUndefined()
|
||||
|
||||
expect(Dark.isActive).toBe(false)
|
||||
expect($q.dark.isActive).toBe(false)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(false)
|
||||
|
||||
Dark.toggle()
|
||||
|
||||
expect(Dark.isActive).toBe(true)
|
||||
expect($q.dark.isActive).toBe(true)
|
||||
expect(
|
||||
document.body.classList.contains('body--dark')
|
||||
).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
8
Frontend-Learner/node_modules/quasar/src/plugins/dialog/Dialog.js
generated
vendored
Normal file
8
Frontend-Learner/node_modules/quasar/src/plugins/dialog/Dialog.js
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import DialogPlugin from './component/DialogPluginComponent.js'
|
||||
import globalDialog from '../../utils/private.dialog/create-dialog.js'
|
||||
|
||||
export default {
|
||||
install ({ $q, parentApp }) {
|
||||
$q.dialog = this.create = globalDialog(DialogPlugin, true, parentApp)
|
||||
}
|
||||
}
|
||||
287
Frontend-Learner/node_modules/quasar/src/plugins/dialog/Dialog.json
generated
vendored
Normal file
287
Frontend-Learner/node_modules/quasar/src/plugins/dialog/Dialog.json
generated
vendored
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
{
|
||||
"mixins": [ "utils/private.dialog/create-dialog" ],
|
||||
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/dialog"
|
||||
},
|
||||
|
||||
"injection": "$q.dialog",
|
||||
|
||||
"methods": {
|
||||
"create": {
|
||||
"tsInjectionPoint": true,
|
||||
"params": {
|
||||
"opts": {
|
||||
"desc": "Dialog options",
|
||||
"tsType": "QDialogOptions",
|
||||
"autoDefineTsType": true,
|
||||
"definition": {
|
||||
"title": {
|
||||
"type": "String",
|
||||
"desc": "A text for the heading title of the dialog",
|
||||
"examples": [ "'Continue?'" ]
|
||||
},
|
||||
|
||||
"message": {
|
||||
"type": "String",
|
||||
"desc": "A text with more information about what needs to be input, selected or confirmed.",
|
||||
"examples": [ "'Are you certain you want to continue?'" ]
|
||||
},
|
||||
|
||||
"html": {
|
||||
"type": "Boolean",
|
||||
"desc": "Render title and message as HTML; This can lead to XSS attacks, so make sure that you sanitize the message first"
|
||||
},
|
||||
|
||||
"position": {
|
||||
"type": "String",
|
||||
"desc": "Position of the Dialog on screen. Standard is centered.",
|
||||
"values": [ "'top'", "'right'", "'bottom'", "'left'", "'standard'" ],
|
||||
"default": "'standard'"
|
||||
},
|
||||
|
||||
"prompt": {
|
||||
"type": "Object",
|
||||
"tsType": "QDialogInputPrompt",
|
||||
"desc": "An object definition of the input field for the prompting question.",
|
||||
"examples": [ "{ model: 'initial-value', type: 'number' }" ],
|
||||
"definition": {
|
||||
"model": {
|
||||
"type": "String",
|
||||
"required": true,
|
||||
"desc": "The initial value of the input"
|
||||
},
|
||||
|
||||
"type": {
|
||||
"type": "String",
|
||||
"desc": "Optional property to determine the input field type",
|
||||
"default": "'text'",
|
||||
"examples": [ "'text'", "'number'", "'textarea'" ]
|
||||
},
|
||||
|
||||
"isValid": {
|
||||
"type": "Function",
|
||||
"desc": "Is typed content valid?",
|
||||
"params": {
|
||||
"val": {
|
||||
"type": "String",
|
||||
"required": true,
|
||||
"desc": "The value of the input"
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "The text passed validation or not"
|
||||
}
|
||||
},
|
||||
|
||||
"...QInputProps": {
|
||||
"type": "Any",
|
||||
"desc": "Any QInput props, like color, label, stackLabel, filled, outlined, rounded, prefix etc",
|
||||
"examples": [
|
||||
"label: 'My Label'",
|
||||
"standout: true",
|
||||
"counter: true",
|
||||
"maxlength: 12"
|
||||
]
|
||||
},
|
||||
|
||||
"...nativeAttributes": {
|
||||
"type": "Object",
|
||||
"desc": "Any native attributes to pass to the prompt control",
|
||||
"examples": [ "# autocomplete: 'off'" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"options": {
|
||||
"type": "Object",
|
||||
"tsType": "QDialogSelectionPrompt",
|
||||
"desc": "An object definition for creating the selection form content",
|
||||
"examples": [ "{ model: null, type: 'radio', items: [ /* ...listOfItems */ ] }" ],
|
||||
"definition": {
|
||||
"model": {
|
||||
"type": [ "String", "Array" ],
|
||||
"required": true,
|
||||
"desc": "The value of the selection (String if it's of type radio or Array otherwise)",
|
||||
"examples": [ "[]" ]
|
||||
},
|
||||
|
||||
"type": {
|
||||
"type": "String",
|
||||
"desc": "The type of selection",
|
||||
"default": "'radio'",
|
||||
"values": [ "'radio'", "'checkbox'", "'toggle'" ]
|
||||
},
|
||||
|
||||
"items": {
|
||||
"type": "Array",
|
||||
"desc": "The list of options to interact with; Equivalent to options prop of the QOptionGroup component",
|
||||
"examples": [
|
||||
"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2' }, { label: 'Option 3', value: 'op3' } ]"
|
||||
]
|
||||
},
|
||||
|
||||
"isValid": {
|
||||
"type": "Function",
|
||||
"desc": "Is the model valid?",
|
||||
"params": {
|
||||
"model": {
|
||||
"type": [ "String", "Array" ],
|
||||
"required": true,
|
||||
"desc": "The current model (String if it's of type radio or Array otherwise)",
|
||||
"examples": [
|
||||
"'opt2'",
|
||||
"[ 'opt1' ]",
|
||||
"[]",
|
||||
"[ 'opt1', 'opt3' ]"
|
||||
]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "The selection passed validation or not"
|
||||
}
|
||||
},
|
||||
|
||||
"...QOptionGroupProps": {
|
||||
"type": "Any",
|
||||
"desc": "Any QOptionGroup props",
|
||||
"examples": [
|
||||
"color: 'deep-purple-4'",
|
||||
"inline: true",
|
||||
"dense: true",
|
||||
"leftLabel: true"
|
||||
]
|
||||
},
|
||||
|
||||
"...nativeAttributes": {
|
||||
"type": "Object",
|
||||
"desc": "Any native attributes to pass to the inner QOptionGroup"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"progress": {
|
||||
"type": [ "Boolean", "Object" ],
|
||||
"desc": "Display a Quasar spinner (if value is true, then the defaults are used); Useful for conveying the idea that something is happening behind the covers; Tip: use along with persistent, ok: false and update() method",
|
||||
"definition": {
|
||||
"spinner": {
|
||||
"type": "Component",
|
||||
"desc": "One of the QSpinners"
|
||||
},
|
||||
"color": {
|
||||
"extends": "color"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"ok": {
|
||||
"type": [ "String", "Object", "Boolean" ],
|
||||
"desc": "Props for an 'OK' button",
|
||||
"definition": {
|
||||
"...props": {
|
||||
"type": "Any",
|
||||
"desc": "See QBtn for available props"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"cancel": {
|
||||
"type": [ "String", "Object", "Boolean" ],
|
||||
"desc": "Props for a 'CANCEL' button",
|
||||
"definition": {
|
||||
"...props": {
|
||||
"type": "Any",
|
||||
"desc": "See QBtn for available props"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"focus": {
|
||||
"type": "String",
|
||||
"desc": "What button to focus, unless you also have 'prompt' or 'options'",
|
||||
"values": [ "'ok'", "'cancel'", "'none'" ],
|
||||
"default": "'ok'"
|
||||
},
|
||||
|
||||
"stackButtons": {
|
||||
"type": "Boolean",
|
||||
"desc": "Makes buttons be stacked instead of vertically aligned"
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"dark": {
|
||||
"extends": "dark",
|
||||
"desc": "Apply dark mode"
|
||||
},
|
||||
|
||||
"persistent": {
|
||||
"type": "Boolean",
|
||||
"desc": "User cannot dismiss Dialog if clicking outside of it or hitting ESC key; Also, an app route change won't dismiss it"
|
||||
},
|
||||
|
||||
"noEscDismiss": {
|
||||
"type": "Boolean",
|
||||
"desc": "User cannot dismiss Dialog by hitting ESC key; No need to set it if 'persistent' prop is also set"
|
||||
},
|
||||
|
||||
"noBackdropDismiss": {
|
||||
"type": "Boolean",
|
||||
"desc": "User cannot dismiss Dialog by clicking outside of it; No need to set it if 'persistent' prop is also set"
|
||||
},
|
||||
|
||||
"noRouteDismiss": {
|
||||
"type": "Boolean",
|
||||
"desc": "Changing route app won't dismiss Dialog; No need to set it if 'persistent' prop is also set"
|
||||
},
|
||||
|
||||
"seamless": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put Dialog into seamless mode; Does not use a backdrop so user is able to interact with the rest of the page too"
|
||||
},
|
||||
|
||||
"maximized": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put Dialog into maximized mode"
|
||||
},
|
||||
|
||||
"fullWidth": {
|
||||
"type": "Boolean",
|
||||
"desc": "Dialog will try to render with same width as the window"
|
||||
},
|
||||
|
||||
"fullHeight": {
|
||||
"type": "Boolean",
|
||||
"desc": "Dialog will try to render with same height as the window"
|
||||
},
|
||||
|
||||
"transitionShow": {
|
||||
"extends": "transition",
|
||||
"default": "'scale'"
|
||||
},
|
||||
|
||||
"transitionHide": {
|
||||
"extends": "transition",
|
||||
"default": "'scale'"
|
||||
},
|
||||
|
||||
"component": {
|
||||
"type": [ "Component", "String" ],
|
||||
"desc": "Use custom dialog component; use along with 'componentProps' prop where possible",
|
||||
"examples": [ "CustomComponent", "'custom-component'" ]
|
||||
},
|
||||
|
||||
"componentProps": {
|
||||
"type": "Object",
|
||||
"desc": "User defined props which will be forwarded to underlying custom component if 'component' prop is used; May also include any built-in QDialog option such as 'persistent' or 'seamless'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
325
Frontend-Learner/node_modules/quasar/src/plugins/dialog/component/DialogPluginComponent.js
generated
vendored
Normal file
325
Frontend-Learner/node_modules/quasar/src/plugins/dialog/component/DialogPluginComponent.js
generated
vendored
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
import { h, ref, computed, watch, toRaw, getCurrentInstance } from 'vue'
|
||||
|
||||
import QDialog from '../../../components/dialog/QDialog.js'
|
||||
import QBtn from '../../../components/btn/QBtn.js'
|
||||
|
||||
import QCard from '../../../components/card/QCard.js'
|
||||
import QCardSection from '../../../components/card/QCardSection.js'
|
||||
import QCardActions from '../../../components/card/QCardActions.js'
|
||||
import QSeparator from '../../../components/separator/QSeparator.js'
|
||||
|
||||
import QInput from '../../../components/input/QInput.js'
|
||||
import QOptionGroup from '../../../components/option-group/QOptionGroup.js'
|
||||
|
||||
import QSpinner from '../../../components/spinner/QSpinner.js'
|
||||
|
||||
import { createComponent } from '../../../utils/private.create/create.js'
|
||||
import useDark, { useDarkProps } from '../../../composables/private.use-dark/use-dark.js'
|
||||
|
||||
import { isKeyCode } from '../../../utils/private.keyboard/key-composition.js'
|
||||
import { isObject } from '../../../utils/is/is.js'
|
||||
|
||||
export default createComponent({
|
||||
name: 'DialogPluginComponent',
|
||||
|
||||
props: {
|
||||
...useDarkProps,
|
||||
|
||||
title: String,
|
||||
message: String,
|
||||
prompt: Object,
|
||||
options: Object,
|
||||
progress: [ Boolean, Object ],
|
||||
|
||||
html: Boolean,
|
||||
|
||||
ok: {
|
||||
type: [ String, Object, Boolean ],
|
||||
default: true
|
||||
},
|
||||
cancel: [ String, Object, Boolean ],
|
||||
focus: {
|
||||
type: String,
|
||||
default: 'ok',
|
||||
validator: v => [ 'ok', 'cancel', 'none' ].includes(v)
|
||||
},
|
||||
|
||||
stackButtons: Boolean,
|
||||
color: String,
|
||||
|
||||
cardClass: [ String, Array, Object ],
|
||||
cardStyle: [ String, Array, Object ]
|
||||
},
|
||||
|
||||
emits: [ 'ok', 'hide' ],
|
||||
|
||||
setup (props, { emit }) {
|
||||
const { proxy } = getCurrentInstance()
|
||||
const { $q } = proxy
|
||||
|
||||
const isDark = useDark(props, $q)
|
||||
|
||||
const dialogRef = ref(null)
|
||||
|
||||
const model = ref(
|
||||
props.prompt !== void 0
|
||||
? props.prompt.model
|
||||
: (props.options !== void 0 ? props.options.model : void 0)
|
||||
)
|
||||
|
||||
const classes = computed(() =>
|
||||
'q-dialog-plugin'
|
||||
+ (isDark.value === true ? ' q-dialog-plugin--dark q-dark' : '')
|
||||
+ (props.progress !== false ? ' q-dialog-plugin--progress' : '')
|
||||
)
|
||||
|
||||
const vmColor = computed(() =>
|
||||
props.color || (isDark.value === true ? 'amber' : 'primary')
|
||||
)
|
||||
|
||||
const spinner = computed(() => (
|
||||
props.progress === false
|
||||
? null
|
||||
: (
|
||||
isObject(props.progress) === true
|
||||
? {
|
||||
component: props.progress.spinner || QSpinner,
|
||||
props: { color: props.progress.color || vmColor.value }
|
||||
}
|
||||
: {
|
||||
component: QSpinner,
|
||||
props: { color: vmColor.value }
|
||||
}
|
||||
)
|
||||
))
|
||||
|
||||
const hasForm = computed(() =>
|
||||
props.prompt !== void 0 || props.options !== void 0
|
||||
)
|
||||
|
||||
const formProps = computed(() => {
|
||||
if (hasForm.value !== true) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const { model, isValid, items, ...formProps } = props.prompt !== void 0
|
||||
? props.prompt
|
||||
: props.options
|
||||
|
||||
return formProps
|
||||
})
|
||||
|
||||
const okLabel = computed(() => (
|
||||
isObject(props.ok) === true
|
||||
? $q.lang.label.ok
|
||||
: (
|
||||
props.ok === true
|
||||
? $q.lang.label.ok
|
||||
: props.ok
|
||||
)
|
||||
))
|
||||
|
||||
const cancelLabel = computed(() => (
|
||||
isObject(props.cancel) === true
|
||||
? $q.lang.label.cancel
|
||||
: (
|
||||
props.cancel === true
|
||||
? $q.lang.label.cancel
|
||||
: props.cancel
|
||||
)
|
||||
))
|
||||
|
||||
const okDisabled = computed(() => {
|
||||
if (props.prompt !== void 0) {
|
||||
return props.prompt.isValid !== void 0
|
||||
&& props.prompt.isValid(model.value) !== true
|
||||
}
|
||||
if (props.options !== void 0) {
|
||||
return props.options.isValid !== void 0
|
||||
&& props.options.isValid(model.value) !== true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
const okProps = computed(() => ({
|
||||
color: vmColor.value,
|
||||
label: okLabel.value,
|
||||
ripple: false,
|
||||
disable: okDisabled.value,
|
||||
...(isObject(props.ok) === true ? props.ok : { flat: true }),
|
||||
'data-autofocus': (props.focus === 'ok' && hasForm.value !== true) || void 0,
|
||||
onClick: onOk
|
||||
}))
|
||||
|
||||
const cancelProps = computed(() => ({
|
||||
color: vmColor.value,
|
||||
label: cancelLabel.value,
|
||||
ripple: false,
|
||||
...(isObject(props.cancel) === true ? props.cancel : { flat: true }),
|
||||
'data-autofocus': (props.focus === 'cancel' && hasForm.value !== true) || void 0,
|
||||
onClick: onCancel
|
||||
}))
|
||||
|
||||
watch(() => props.prompt && props.prompt.model, onUpdateModel)
|
||||
watch(() => props.options && props.options.model, onUpdateModel)
|
||||
|
||||
function show () {
|
||||
dialogRef.value.show()
|
||||
}
|
||||
|
||||
function hide () {
|
||||
dialogRef.value.hide()
|
||||
}
|
||||
|
||||
function onOk () {
|
||||
emit('ok', toRaw(model.value))
|
||||
hide()
|
||||
}
|
||||
|
||||
function onCancel () {
|
||||
hide()
|
||||
}
|
||||
|
||||
function onDialogHide () {
|
||||
emit('hide')
|
||||
}
|
||||
|
||||
function onUpdateModel (val) {
|
||||
model.value = val
|
||||
}
|
||||
|
||||
function onInputKeyup (evt) {
|
||||
// if ENTER key
|
||||
if (
|
||||
okDisabled.value !== true
|
||||
&& props.prompt.type !== 'textarea'
|
||||
&& isKeyCode(evt, 13) === true
|
||||
) {
|
||||
onOk()
|
||||
}
|
||||
}
|
||||
|
||||
function getSection (classes, text) {
|
||||
return props.html === true
|
||||
? h(QCardSection, {
|
||||
class: classes,
|
||||
innerHTML: text
|
||||
})
|
||||
: h(QCardSection, { class: classes }, () => text)
|
||||
}
|
||||
|
||||
function getPrompt () {
|
||||
return [
|
||||
h(QInput, {
|
||||
color: vmColor.value,
|
||||
dense: true,
|
||||
autofocus: true,
|
||||
dark: isDark.value,
|
||||
...formProps.value,
|
||||
modelValue: model.value,
|
||||
'onUpdate:modelValue': onUpdateModel,
|
||||
onKeyup: onInputKeyup
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
function getOptions () {
|
||||
return [
|
||||
h(QOptionGroup, {
|
||||
color: vmColor.value,
|
||||
options: props.options.items,
|
||||
dark: isDark.value,
|
||||
...formProps.value,
|
||||
modelValue: model.value,
|
||||
'onUpdate:modelValue': onUpdateModel
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
function getButtons () {
|
||||
const child = []
|
||||
|
||||
props.cancel && child.push(
|
||||
h(QBtn, cancelProps.value)
|
||||
)
|
||||
|
||||
props.ok && child.push(
|
||||
h(QBtn, okProps.value)
|
||||
)
|
||||
|
||||
return h(QCardActions, {
|
||||
class: props.stackButtons === true ? 'items-end' : '',
|
||||
vertical: props.stackButtons,
|
||||
align: 'right'
|
||||
}, () => child)
|
||||
}
|
||||
|
||||
function getCardContent () {
|
||||
const child = []
|
||||
|
||||
props.title && child.push(
|
||||
getSection('q-dialog__title', props.title)
|
||||
)
|
||||
|
||||
props.progress !== false && child.push(
|
||||
h(
|
||||
QCardSection,
|
||||
{ class: 'q-dialog__progress' },
|
||||
() => h(spinner.value.component, spinner.value.props)
|
||||
)
|
||||
)
|
||||
|
||||
props.message && child.push(
|
||||
getSection('q-dialog__message', props.message)
|
||||
)
|
||||
|
||||
if (props.prompt !== void 0) {
|
||||
child.push(
|
||||
h(
|
||||
QCardSection,
|
||||
{ class: 'scroll q-dialog-plugin__form' },
|
||||
getPrompt
|
||||
)
|
||||
)
|
||||
}
|
||||
else if (props.options !== void 0) {
|
||||
child.push(
|
||||
h(QSeparator, { dark: isDark.value }),
|
||||
h(
|
||||
QCardSection,
|
||||
{ class: 'scroll q-dialog-plugin__form' },
|
||||
getOptions
|
||||
),
|
||||
h(QSeparator, { dark: isDark.value })
|
||||
)
|
||||
}
|
||||
|
||||
if (props.ok || props.cancel) {
|
||||
child.push(getButtons())
|
||||
}
|
||||
|
||||
return child
|
||||
}
|
||||
|
||||
function getContent () {
|
||||
return [
|
||||
h(QCard, {
|
||||
class: [
|
||||
classes.value,
|
||||
props.cardClass
|
||||
],
|
||||
style: props.cardStyle,
|
||||
dark: isDark.value
|
||||
}, getCardContent)
|
||||
]
|
||||
}
|
||||
|
||||
// expose public methods
|
||||
Object.assign(proxy, { show, hide })
|
||||
|
||||
return () => h(QDialog, {
|
||||
ref: dialogRef,
|
||||
onHide: onDialogHide
|
||||
}, getContent)
|
||||
}
|
||||
})
|
||||
11
Frontend-Learner/node_modules/quasar/src/plugins/dialog/component/DialogPluginComponent.sass
generated
vendored
Normal file
11
Frontend-Learner/node_modules/quasar/src/plugins/dialog/component/DialogPluginComponent.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
.q-dialog-plugin
|
||||
width: 400px
|
||||
|
||||
&__form
|
||||
max-height: 50vh
|
||||
|
||||
.q-card__section + .q-card__section
|
||||
padding-top: 0
|
||||
|
||||
&--progress
|
||||
text-align: center
|
||||
77
Frontend-Learner/node_modules/quasar/src/plugins/icon-set/IconSet.js
generated
vendored
Normal file
77
Frontend-Learner/node_modules/quasar/src/plugins/icon-set/IconSet.js
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
import { injectProp } from '../../utils/private.inject-obj-prop/inject-obj-prop.js'
|
||||
|
||||
import materialIcons from '../../../icon-set/material-icons.js'
|
||||
|
||||
const Plugin = createReactivePlugin({
|
||||
iconMapFn: null,
|
||||
__qIconSet: {}
|
||||
}, {
|
||||
// props: object
|
||||
|
||||
set (setObject, ssrContext) {
|
||||
const def = { ...setObject }
|
||||
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
if (ssrContext === void 0) {
|
||||
console.error('SSR ERROR: second param required: IconSet.set(iconSet, ssrContext)')
|
||||
return
|
||||
}
|
||||
|
||||
def.set = ssrContext.$q.iconSet.set
|
||||
Object.assign(ssrContext.$q.iconSet, def)
|
||||
}
|
||||
else {
|
||||
def.set = Plugin.set
|
||||
Object.assign(Plugin.__qIconSet, def)
|
||||
}
|
||||
},
|
||||
|
||||
install ({ $q, iconSet, ssrContext }) {
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
const initialSet = iconSet || materialIcons
|
||||
|
||||
$q.iconMapFn = ssrContext.$q.config.iconMapFn || this.iconMapFn || null
|
||||
$q.iconSet = {}
|
||||
$q.iconSet.set = setObject => {
|
||||
this.set(setObject, ssrContext)
|
||||
}
|
||||
|
||||
$q.iconSet.set(initialSet)
|
||||
|
||||
// one-time SSR server operation
|
||||
if (
|
||||
this.props === void 0
|
||||
|| this.props.name !== initialSet.name
|
||||
) {
|
||||
this.props = { ...initialSet }
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($q.config.iconMapFn !== void 0) {
|
||||
this.iconMapFn = $q.config.iconMapFn
|
||||
}
|
||||
|
||||
$q.iconSet = this.__qIconSet
|
||||
injectProp($q, 'iconMapFn', () => this.iconMapFn, val => { this.iconMapFn = val })
|
||||
|
||||
if (this.__installed === true) {
|
||||
iconSet !== void 0 && this.set(iconSet)
|
||||
}
|
||||
else {
|
||||
this.props = new Proxy(this.__qIconSet, {
|
||||
get () { return Reflect.get(...arguments) },
|
||||
|
||||
ownKeys (target) {
|
||||
return Reflect.ownKeys(target)
|
||||
.filter(key => key !== 'set')
|
||||
}
|
||||
})
|
||||
|
||||
this.set(iconSet || materialIcons)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default Plugin
|
||||
1417
Frontend-Learner/node_modules/quasar/src/plugins/icon-set/IconSet.json
generated
vendored
Normal file
1417
Frontend-Learner/node_modules/quasar/src/plugins/icon-set/IconSet.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
346
Frontend-Learner/node_modules/quasar/src/plugins/icon-set/IconSet.test.js
generated
vendored
Normal file
346
Frontend-Learner/node_modules/quasar/src/plugins/icon-set/IconSet.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import IconSet from './IconSet.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
describe('[IconSet API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
|
||||
expect(wrapper.vm.$q.iconSet).toBeDefined()
|
||||
expect(wrapper.vm.$q.iconSet.name).toBe(IconSet.props.name)
|
||||
expect(wrapper.vm.$q.iconSet.set).toBe(IconSet.set)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)props]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(IconSet.props).toStrictEqual({
|
||||
name: expect.any(String),
|
||||
type: {
|
||||
positive: expect.any(String),
|
||||
negative: expect.any(String),
|
||||
info: expect.any(String),
|
||||
warning: expect.any(String)
|
||||
},
|
||||
arrow: {
|
||||
up: expect.any(String),
|
||||
right: expect.any(String),
|
||||
down: expect.any(String),
|
||||
left: expect.any(String),
|
||||
dropdown: expect.any(String)
|
||||
},
|
||||
chevron: {
|
||||
left: expect.any(String),
|
||||
right: expect.any(String)
|
||||
},
|
||||
colorPicker: {
|
||||
spectrum: expect.any(String),
|
||||
tune: expect.any(String),
|
||||
palette: expect.any(String)
|
||||
},
|
||||
pullToRefresh: {
|
||||
icon: expect.any(String)
|
||||
},
|
||||
carousel: {
|
||||
left: expect.any(String),
|
||||
right: expect.any(String),
|
||||
up: expect.any(String),
|
||||
down: expect.any(String),
|
||||
navigationIcon: expect.any(String)
|
||||
},
|
||||
chip: {
|
||||
remove: expect.any(String),
|
||||
selected: expect.any(String)
|
||||
},
|
||||
datetime: {
|
||||
arrowLeft: expect.any(String),
|
||||
arrowRight: expect.any(String),
|
||||
now: expect.any(String),
|
||||
today: expect.any(String)
|
||||
},
|
||||
editor: {
|
||||
bold: expect.any(String),
|
||||
italic: expect.any(String),
|
||||
strikethrough: expect.any(String),
|
||||
underline: expect.any(String),
|
||||
unorderedList: expect.any(String),
|
||||
orderedList: expect.any(String),
|
||||
subscript: expect.any(String),
|
||||
superscript: expect.any(String),
|
||||
hyperlink: expect.any(String),
|
||||
toggleFullscreen: expect.any(String),
|
||||
quote: expect.any(String),
|
||||
left: expect.any(String),
|
||||
center: expect.any(String),
|
||||
right: expect.any(String),
|
||||
justify: expect.any(String),
|
||||
print: expect.any(String),
|
||||
outdent: expect.any(String),
|
||||
indent: expect.any(String),
|
||||
removeFormat: expect.any(String),
|
||||
formatting: expect.any(String),
|
||||
fontSize: expect.any(String),
|
||||
align: expect.any(String),
|
||||
hr: expect.any(String),
|
||||
undo: expect.any(String),
|
||||
redo: expect.any(String),
|
||||
heading: expect.any(String),
|
||||
code: expect.any(String),
|
||||
size: expect.any(String),
|
||||
font: expect.any(String),
|
||||
viewSource: expect.any(String)
|
||||
},
|
||||
expansionItem: {
|
||||
icon: expect.any(String),
|
||||
denseIcon: expect.any(String)
|
||||
},
|
||||
fab: {
|
||||
icon: expect.any(String),
|
||||
activeIcon: expect.any(String)
|
||||
},
|
||||
field: {
|
||||
clear: expect.any(String),
|
||||
error: expect.any(String)
|
||||
},
|
||||
pagination: {
|
||||
first: expect.any(String),
|
||||
prev: expect.any(String),
|
||||
next: expect.any(String),
|
||||
last: expect.any(String)
|
||||
},
|
||||
rating: {
|
||||
icon: expect.any(String)
|
||||
},
|
||||
stepper: {
|
||||
done: expect.any(String),
|
||||
active: expect.any(String),
|
||||
error: expect.any(String)
|
||||
},
|
||||
tabs: {
|
||||
left: expect.any(String),
|
||||
right: expect.any(String),
|
||||
up: expect.any(String),
|
||||
down: expect.any(String)
|
||||
},
|
||||
table: {
|
||||
arrowUp: expect.any(String),
|
||||
warning: expect.any(String),
|
||||
firstPage: expect.any(String),
|
||||
prevPage: expect.any(String),
|
||||
nextPage: expect.any(String),
|
||||
lastPage: expect.any(String)
|
||||
},
|
||||
tree: {
|
||||
icon: expect.any(String)
|
||||
},
|
||||
uploader: {
|
||||
done: expect.any(String),
|
||||
clear: expect.any(String),
|
||||
add: expect.any(String),
|
||||
upload: expect.any(String),
|
||||
removeQueue: expect.any(String),
|
||||
removeUploaded: expect.any(String)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('can be set', () => {
|
||||
const wrapper = mountPlugin()
|
||||
|
||||
IconSet.props.name = 'new-icon-set'
|
||||
expect(IconSet.props.name).toBe('new-icon-set')
|
||||
expect(wrapper.vm.$q.iconSet.name).toBe('new-icon-set')
|
||||
|
||||
wrapper.vm.$q.iconSet.name = 'another-icon-set'
|
||||
expect(IconSet.props.name).toBe('another-icon-set')
|
||||
expect(wrapper.vm.$q.iconSet.name).toBe('another-icon-set')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)iconMapFn]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(IconSet.iconMapFn).$any([
|
||||
expect.any(Function),
|
||||
null
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)set]', () => {
|
||||
test('should be callable', () => {
|
||||
const wrapper = mountPlugin()
|
||||
|
||||
expect(
|
||||
IconSet.set({
|
||||
name: 'new-icon-set',
|
||||
type: {
|
||||
positive: 'check_circle',
|
||||
negative: 'warning',
|
||||
info: 'info',
|
||||
warning: 'priority_high'
|
||||
},
|
||||
arrow: {
|
||||
up: 'arrow_upward',
|
||||
right: 'arrow_forward',
|
||||
down: 'arrow_downward',
|
||||
left: 'arrow_back',
|
||||
dropdown: 'arrow_drop_down'
|
||||
},
|
||||
chevron: {
|
||||
left: 'chevron_left',
|
||||
right: 'chevron_right'
|
||||
},
|
||||
colorPicker: {
|
||||
spectrum: 'gradient',
|
||||
tune: 'tune',
|
||||
palette: 'style'
|
||||
},
|
||||
pullToRefresh: {
|
||||
icon: 'refresh'
|
||||
},
|
||||
carousel: {
|
||||
left: 'chevron_left',
|
||||
right: 'chevron_right',
|
||||
up: 'keyboard_arrow_up',
|
||||
down: 'keyboard_arrow_down',
|
||||
navigationIcon: 'lens'
|
||||
},
|
||||
chip: {
|
||||
remove: 'cancel',
|
||||
selected: 'check'
|
||||
},
|
||||
datetime: {
|
||||
arrowLeft: 'chevron_left',
|
||||
arrowRight: 'chevron_right',
|
||||
now: 'access_time',
|
||||
today: 'today'
|
||||
},
|
||||
editor: {
|
||||
bold: 'format_bold',
|
||||
italic: 'format_italic',
|
||||
strikethrough: 'strikethrough_s',
|
||||
underline: 'format_underlined',
|
||||
unorderedList: 'format_list_bulleted',
|
||||
orderedList: 'format_list_numbered',
|
||||
subscript: 'vertical_align_bottom',
|
||||
superscript: 'vertical_align_top',
|
||||
hyperlink: 'link',
|
||||
toggleFullscreen: 'fullscreen',
|
||||
quote: 'format_quote',
|
||||
left: 'format_align_left',
|
||||
center: 'format_align_center',
|
||||
right: 'format_align_right',
|
||||
justify: 'format_align_justify',
|
||||
print: 'print',
|
||||
outdent: 'format_indent_decrease',
|
||||
indent: 'format_indent_increase',
|
||||
removeFormat: 'format_clear',
|
||||
formatting: 'text_format',
|
||||
fontSize: 'format_size',
|
||||
align: 'format_align_left',
|
||||
hr: 'remove',
|
||||
undo: 'undo',
|
||||
redo: 'redo',
|
||||
heading: 'format_size',
|
||||
heading1: 'format_size',
|
||||
heading2: 'format_size',
|
||||
heading3: 'format_size',
|
||||
heading4: 'format_size',
|
||||
heading5: 'format_size',
|
||||
heading6: 'format_size',
|
||||
code: 'code',
|
||||
size: 'format_size',
|
||||
size1: 'format_size',
|
||||
size2: 'format_size',
|
||||
size3: 'format_size',
|
||||
size4: 'format_size',
|
||||
size5: 'format_size',
|
||||
size6: 'format_size',
|
||||
size7: 'format_size',
|
||||
font: 'font_download',
|
||||
viewSource: 'code'
|
||||
},
|
||||
expansionItem: {
|
||||
icon: 'keyboard_arrow_down',
|
||||
denseIcon: 'arrow_drop_down'
|
||||
},
|
||||
fab: {
|
||||
icon: 'add',
|
||||
activeIcon: 'close'
|
||||
},
|
||||
field: {
|
||||
clear: 'cancel',
|
||||
error: 'error'
|
||||
},
|
||||
pagination: {
|
||||
first: 'first_page',
|
||||
prev: 'keyboard_arrow_left',
|
||||
next: 'keyboard_arrow_right',
|
||||
last: 'last_page'
|
||||
},
|
||||
rating: {
|
||||
icon: 'grade'
|
||||
},
|
||||
stepper: {
|
||||
done: 'check',
|
||||
active: 'edit',
|
||||
error: 'warning'
|
||||
},
|
||||
tabs: {
|
||||
left: 'chevron_left',
|
||||
right: 'chevron_right',
|
||||
up: 'keyboard_arrow_up',
|
||||
down: 'keyboard_arrow_down'
|
||||
},
|
||||
table: {
|
||||
arrowUp: 'arrow_upward',
|
||||
warning: 'warning',
|
||||
firstPage: 'first_page',
|
||||
prevPage: 'chevron_left',
|
||||
nextPage: 'chevron_right',
|
||||
lastPage: 'last_page'
|
||||
},
|
||||
tree: {
|
||||
icon: 'play_arrow'
|
||||
},
|
||||
uploader: {
|
||||
done: 'done',
|
||||
clear: 'clear',
|
||||
add: 'add_box',
|
||||
upload: 'cloud_upload',
|
||||
removeQueue: 'clear_all',
|
||||
removeUploaded: 'done_all'
|
||||
}
|
||||
})
|
||||
).toBeUndefined()
|
||||
|
||||
expect(IconSet.props.name).toBe('new-icon-set')
|
||||
expect(wrapper.vm.$q.iconSet.name).toBe('new-icon-set')
|
||||
})
|
||||
|
||||
test('should work with an imported icon set', async () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
const { default: newIconSet } = await import('quasar/icon-set/fontawesome-v6.js')
|
||||
|
||||
IconSet.set(newIconSet)
|
||||
expect(IconSet.props.name).toBe(newIconSet.name)
|
||||
expect($q.iconSet.name).toBe(newIconSet.name)
|
||||
|
||||
const { default: anotherIconSet } = await import('quasar/icon-set/ionicons-v4.js')
|
||||
$q.iconSet.set(anotherIconSet)
|
||||
expect(IconSet.props.name).toBe(anotherIconSet.name)
|
||||
expect($q.iconSet.name).toBe(anotherIconSet.name)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
117
Frontend-Learner/node_modules/quasar/src/plugins/lang/Lang.js
generated
vendored
Normal file
117
Frontend-Learner/node_modules/quasar/src/plugins/lang/Lang.js
generated
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
|
||||
import defaultLang from '../../../lang/en-US.js'
|
||||
|
||||
function getLocale () {
|
||||
if (__QUASAR_SSR_SERVER__) return
|
||||
|
||||
const val = Array.isArray(navigator.languages) === true && navigator.languages.length !== 0
|
||||
? navigator.languages[ 0 ]
|
||||
: navigator.language
|
||||
|
||||
if (typeof val === 'string') {
|
||||
return val.split(/[-_]/).map((v, i) => (
|
||||
i === 0
|
||||
? v.toLowerCase()
|
||||
: (
|
||||
i > 1 || v.length < 4
|
||||
? v.toUpperCase()
|
||||
: (v[ 0 ].toUpperCase() + v.slice(1).toLowerCase())
|
||||
)
|
||||
)).join('-')
|
||||
}
|
||||
}
|
||||
|
||||
const Plugin = createReactivePlugin({
|
||||
__qLang: {}
|
||||
}, {
|
||||
// props: object
|
||||
// __langConfig: object
|
||||
|
||||
getLocale,
|
||||
|
||||
set (langObject = defaultLang, ssrContext) {
|
||||
const lang = {
|
||||
...langObject,
|
||||
rtl: langObject.rtl === true,
|
||||
getLocale
|
||||
}
|
||||
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
if (ssrContext === void 0) {
|
||||
console.error('SSR ERROR: second param required: Lang.set(lang, ssrContext)')
|
||||
return
|
||||
}
|
||||
|
||||
lang.set = ssrContext.$q.lang.set
|
||||
|
||||
if (ssrContext.$q.config.lang === void 0 || ssrContext.$q.config.lang.noHtmlAttrs !== true) {
|
||||
const dir = lang.rtl === true ? 'rtl' : 'ltr'
|
||||
const attrs = `lang=${ lang.isoName } dir=${ dir }`
|
||||
|
||||
ssrContext._meta.htmlAttrs = ssrContext.__qPrevLang !== void 0
|
||||
? ssrContext._meta.htmlAttrs.replace(ssrContext.__qPrevLang, attrs)
|
||||
: attrs
|
||||
|
||||
ssrContext.__qPrevLang = attrs
|
||||
}
|
||||
|
||||
ssrContext.$q.lang = lang
|
||||
}
|
||||
else {
|
||||
lang.set = Plugin.set
|
||||
|
||||
if (Plugin.__langConfig === void 0 || Plugin.__langConfig.noHtmlAttrs !== true) {
|
||||
const el = document.documentElement
|
||||
el.setAttribute('dir', lang.rtl === true ? 'rtl' : 'ltr')
|
||||
el.setAttribute('lang', lang.isoName)
|
||||
}
|
||||
|
||||
Object.assign(Plugin.__qLang, lang)
|
||||
}
|
||||
},
|
||||
|
||||
install ({ $q, lang, ssrContext }) {
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
const initialLang = lang || defaultLang
|
||||
|
||||
$q.lang = {}
|
||||
$q.lang.set = langObject => {
|
||||
this.set(langObject, ssrContext)
|
||||
}
|
||||
|
||||
$q.lang.set(initialLang)
|
||||
|
||||
// one-time SSR server operation
|
||||
if (
|
||||
this.props === void 0
|
||||
|| this.props.isoName !== initialLang.isoName
|
||||
) {
|
||||
this.props = { ...initialLang }
|
||||
}
|
||||
}
|
||||
else {
|
||||
$q.lang = Plugin.__qLang
|
||||
Plugin.__langConfig = $q.config.lang
|
||||
|
||||
if (this.__installed === true) {
|
||||
lang !== void 0 && this.set(lang)
|
||||
}
|
||||
else {
|
||||
this.props = new Proxy(this.__qLang, {
|
||||
get () { return Reflect.get(...arguments) },
|
||||
|
||||
ownKeys (target) {
|
||||
return Reflect.ownKeys(target)
|
||||
.filter(key => key !== 'set' && key !== 'getLocale')
|
||||
}
|
||||
})
|
||||
|
||||
this.set(lang || defaultLang)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default Plugin
|
||||
export { defaultLang }
|
||||
1100
Frontend-Learner/node_modules/quasar/src/plugins/lang/Lang.json
generated
vendored
Normal file
1100
Frontend-Learner/node_modules/quasar/src/plugins/lang/Lang.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
293
Frontend-Learner/node_modules/quasar/src/plugins/lang/Lang.test.js
generated
vendored
Normal file
293
Frontend-Learner/node_modules/quasar/src/plugins/lang/Lang.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import Lang from './Lang.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
describe('[Lang API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
|
||||
expect(wrapper.vm.$q.lang).toBeDefined()
|
||||
expect(wrapper.vm.$q.lang.name).toBe(Lang.props.name)
|
||||
expect(wrapper.vm.$q.lang.set).toBe(Lang.set)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)props]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(Lang.props).toStrictEqual({
|
||||
isoName: expect.any(String),
|
||||
nativeName: expect.any(String),
|
||||
rtl: expect.any(Boolean),
|
||||
label: {
|
||||
clear: expect.any(String),
|
||||
ok: expect.any(String),
|
||||
cancel: expect.any(String),
|
||||
close: expect.any(String),
|
||||
set: expect.any(String),
|
||||
select: expect.any(String),
|
||||
reset: expect.any(String),
|
||||
remove: expect.any(String),
|
||||
update: expect.any(String),
|
||||
create: expect.any(String),
|
||||
search: expect.any(String),
|
||||
filter: expect.any(String),
|
||||
refresh: expect.any(String),
|
||||
expand: expect.any(Function),
|
||||
collapse: expect.any(Function)
|
||||
},
|
||||
date: {
|
||||
days: expect.any(Array),
|
||||
daysShort: expect.any(Array),
|
||||
months: expect.any(Array),
|
||||
monthsShort: expect.any(Array),
|
||||
firstDayOfWeek: expect.any(Number),
|
||||
format24h: expect.any(Boolean),
|
||||
pluralDay: expect.any(String),
|
||||
prevMonth: expect.any(String),
|
||||
nextMonth: expect.any(String),
|
||||
prevYear: expect.any(String),
|
||||
nextYear: expect.any(String),
|
||||
today: expect.any(String),
|
||||
prevRangeYears: expect.any(Function),
|
||||
nextRangeYears: expect.any(Function)
|
||||
},
|
||||
table: {
|
||||
noData: expect.any(String),
|
||||
noResults: expect.any(String),
|
||||
loading: expect.any(String),
|
||||
selectedRecords: expect.any(Function),
|
||||
recordsPerPage: expect.any(String),
|
||||
allRows: expect.any(String),
|
||||
pagination: expect.any(Function),
|
||||
columns: expect.any(String)
|
||||
},
|
||||
pagination: {
|
||||
first: expect.any(String),
|
||||
last: expect.any(String),
|
||||
next: expect.any(String),
|
||||
prev: expect.any(String)
|
||||
},
|
||||
editor: {
|
||||
url: expect.any(String),
|
||||
bold: expect.any(String),
|
||||
italic: expect.any(String),
|
||||
strikethrough: expect.any(String),
|
||||
underline: expect.any(String),
|
||||
unorderedList: expect.any(String),
|
||||
orderedList: expect.any(String),
|
||||
subscript: expect.any(String),
|
||||
superscript: expect.any(String),
|
||||
hyperlink: expect.any(String),
|
||||
toggleFullscreen: expect.any(String),
|
||||
quote: expect.any(String),
|
||||
left: expect.any(String),
|
||||
center: expect.any(String),
|
||||
right: expect.any(String),
|
||||
justify: expect.any(String),
|
||||
print: expect.any(String),
|
||||
outdent: expect.any(String),
|
||||
indent: expect.any(String),
|
||||
removeFormat: expect.any(String),
|
||||
formatting: expect.any(String),
|
||||
fontSize: expect.any(String),
|
||||
align: expect.any(String),
|
||||
hr: expect.any(String),
|
||||
undo: expect.any(String),
|
||||
redo: expect.any(String),
|
||||
heading1: expect.any(String),
|
||||
heading2: expect.any(String),
|
||||
heading3: expect.any(String),
|
||||
heading4: expect.any(String),
|
||||
heading5: expect.any(String),
|
||||
heading6: expect.any(String),
|
||||
paragraph: expect.any(String),
|
||||
code: expect.any(String),
|
||||
size1: expect.any(String),
|
||||
size2: expect.any(String),
|
||||
size3: expect.any(String),
|
||||
size4: expect.any(String),
|
||||
size5: expect.any(String),
|
||||
size6: expect.any(String),
|
||||
size7: expect.any(String),
|
||||
defaultFont: expect.any(String),
|
||||
viewSource: expect.any(String)
|
||||
},
|
||||
tree: {
|
||||
noNodes: expect.any(String),
|
||||
noResults: expect.any(String)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('can be set', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
|
||||
Lang.props.nativeName = 'new-lang'
|
||||
expect(Lang.props.nativeName).toBe('new-lang')
|
||||
expect($q.lang.nativeName).toBe('new-lang')
|
||||
|
||||
$q.lang.nativeName = 'another-lang'
|
||||
expect(Lang.props.nativeName).toBe('another-lang')
|
||||
expect($q.lang.nativeName).toBe('another-lang')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)set]', () => {
|
||||
test('should be callable', () => {
|
||||
const wrapper = mountPlugin()
|
||||
|
||||
expect(
|
||||
Lang.set({
|
||||
isoName: 'en-US',
|
||||
nativeName: 'New Language',
|
||||
rtl: true,
|
||||
label: {
|
||||
clear: 'Clear',
|
||||
ok: 'OK',
|
||||
cancel: 'Cancel',
|
||||
close: 'Close',
|
||||
set: 'Set',
|
||||
select: 'Select',
|
||||
reset: 'Reset',
|
||||
remove: 'Remove',
|
||||
update: 'Update',
|
||||
create: 'Create',
|
||||
search: 'Search',
|
||||
filter: 'Filter',
|
||||
refresh: 'Refresh',
|
||||
expand: label => (label ? `Expand '${ label }'` : 'Expand'),
|
||||
collapse: label => (label ? `Collapse '${ label }'` : 'Collapse')
|
||||
},
|
||||
date: {
|
||||
days: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
|
||||
daysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
|
||||
months: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
|
||||
monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
|
||||
firstDayOfWeek: 0,
|
||||
format24h: true,
|
||||
pluralDay: 'days',
|
||||
prevMonth: expect.any(String),
|
||||
nextMonth: expect.any(String),
|
||||
prevYear: expect.any(String),
|
||||
nextYear: expect.any(String),
|
||||
today: expect.any(String),
|
||||
prevRangeYears: expect.any(Function),
|
||||
nextRangeYears: expect.any(Function)
|
||||
},
|
||||
table: {
|
||||
noData: 'No data available',
|
||||
noResults: 'No matching records found',
|
||||
loading: 'Loading...',
|
||||
selectedRecords: rows => `${ rows } records selected`,
|
||||
recordsPerPage: 'Records per page:',
|
||||
allRows: 'All',
|
||||
pagination: (start, end, total) => start + '-' + end + ' of ' + total,
|
||||
columns: 'Columns'
|
||||
},
|
||||
pagination: {
|
||||
first: expect.any(String),
|
||||
last: expect.any(String),
|
||||
next: expect.any(String),
|
||||
prev: expect.any(String)
|
||||
},
|
||||
editor: {
|
||||
url: 'URL',
|
||||
bold: 'Bold',
|
||||
italic: 'Italic',
|
||||
strikethrough: 'Strikethrough',
|
||||
underline: 'Underline',
|
||||
unorderedList: 'Unordered List',
|
||||
orderedList: 'Ordered List',
|
||||
subscript: 'Subscript',
|
||||
superscript: 'Superscript',
|
||||
hyperlink: 'Hyperlink',
|
||||
toggleFullscreen: 'Toggle Fullscreen',
|
||||
quote: 'Quote',
|
||||
left: 'Left align',
|
||||
center: 'Center align',
|
||||
right: 'Right align',
|
||||
justify: 'Justify align',
|
||||
print: 'Print',
|
||||
outdent: 'Decrease indentation',
|
||||
indent: 'Increase indentation',
|
||||
removeFormat: 'Remove formatting',
|
||||
formatting: 'Formatting',
|
||||
fontSize: 'Font Size',
|
||||
align: 'Align',
|
||||
hr: 'Insert Horizontal Rule',
|
||||
undo: 'Undo',
|
||||
redo: 'Redo',
|
||||
heading1: 'Heading 1',
|
||||
heading2: 'Heading 2',
|
||||
heading3: 'Heading 3',
|
||||
heading4: 'Heading 4',
|
||||
heading5: 'Heading 5',
|
||||
heading6: 'Heading 6',
|
||||
paragraph: 'Paragraph',
|
||||
code: 'Code',
|
||||
size1: 'Very small',
|
||||
size2: 'A bit small',
|
||||
size3: 'Normal',
|
||||
size4: 'Medium-large',
|
||||
size5: 'Big',
|
||||
size6: 'Very big',
|
||||
size7: 'Maximum',
|
||||
defaultFont: 'Default Font',
|
||||
viewSource: 'View Source'
|
||||
},
|
||||
tree: {
|
||||
noNodes: 'No nodes available',
|
||||
noResults: 'No matching nodes found'
|
||||
}
|
||||
})
|
||||
).toBeUndefined()
|
||||
|
||||
expect(Lang.props.nativeName).toBe('New Language')
|
||||
expect(wrapper.vm.$q.lang.nativeName).toBe('New Language')
|
||||
})
|
||||
|
||||
test('should work with an imported lang pack', async () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
const { default: deLang } = await import('quasar/lang/de-DE.js')
|
||||
|
||||
Lang.set(deLang)
|
||||
expect(Lang.props.nativeName).toBe(deLang.nativeName)
|
||||
expect($q.lang.nativeName).toBe(deLang.nativeName)
|
||||
|
||||
const { default: itLang } = await import('quasar/lang/it.js')
|
||||
$q.lang.set(itLang)
|
||||
expect(Lang.props.nativeName).toBe(itLang.nativeName)
|
||||
expect($q.lang.nativeName).toBe(itLang.nativeName)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getLocale]', () => {
|
||||
test('should be callable', () => {
|
||||
const wrapper = mountPlugin()
|
||||
|
||||
expect(
|
||||
Lang.getLocale()
|
||||
).$any([
|
||||
expect.any(String),
|
||||
undefined
|
||||
])
|
||||
|
||||
expect(
|
||||
wrapper.vm.$q.lang.getLocale()
|
||||
).$any([
|
||||
expect.any(String),
|
||||
undefined
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
77
Frontend-Learner/node_modules/quasar/src/plugins/loading-bar/LoadingBar.js
generated
vendored
Normal file
77
Frontend-Learner/node_modules/quasar/src/plugins/loading-bar/LoadingBar.js
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import { h, ref } from 'vue'
|
||||
|
||||
import QAjaxBar from '../../components/ajax-bar/QAjaxBar.js'
|
||||
import { createChildApp } from '../../install-quasar.js'
|
||||
|
||||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
import { noop } from '../../utils/event/event.js'
|
||||
import { createGlobalNode } from '../../utils/private.config/nodes.js'
|
||||
import { isObject } from '../../utils/is/is.js'
|
||||
|
||||
const barRef = ref(null)
|
||||
|
||||
const Plugin = createReactivePlugin({
|
||||
isActive: false
|
||||
}, {
|
||||
start: noop,
|
||||
stop: noop,
|
||||
increment: noop,
|
||||
setDefaults: noop,
|
||||
|
||||
install ({ $q, parentApp }) {
|
||||
$q.loadingBar = this
|
||||
|
||||
if (__QUASAR_SSR_SERVER__) return
|
||||
|
||||
if (this.__installed === true) {
|
||||
if ($q.config.loadingBar !== void 0) {
|
||||
this.setDefaults($q.config.loadingBar)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const props = ref(
|
||||
$q.config.loadingBar !== void 0
|
||||
? { ...$q.config.loadingBar }
|
||||
: {}
|
||||
)
|
||||
|
||||
function onStart () {
|
||||
Plugin.isActive = true
|
||||
}
|
||||
|
||||
function onStop () {
|
||||
Plugin.isActive = false
|
||||
}
|
||||
|
||||
const el = createGlobalNode('q-loading-bar')
|
||||
|
||||
createChildApp({
|
||||
name: 'LoadingBar',
|
||||
|
||||
// hide App from Vue devtools
|
||||
devtools: { hide: true },
|
||||
|
||||
setup: () => () => h(QAjaxBar, { ...props.value, onStart, onStop, ref: barRef })
|
||||
}, parentApp).mount(el)
|
||||
|
||||
Object.assign(this, {
|
||||
start (speed) {
|
||||
barRef.value.start(speed)
|
||||
},
|
||||
stop () {
|
||||
barRef.value.stop()
|
||||
},
|
||||
increment () {
|
||||
barRef.value.increment.apply(null, arguments)
|
||||
},
|
||||
setDefaults (opts) {
|
||||
if (isObject(opts) === true) {
|
||||
Object.assign(props.value, opts)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
export default Plugin
|
||||
68
Frontend-Learner/node_modules/quasar/src/plugins/loading-bar/LoadingBar.json
generated
vendored
Normal file
68
Frontend-Learner/node_modules/quasar/src/plugins/loading-bar/LoadingBar.json
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/loading-bar"
|
||||
},
|
||||
|
||||
"injection": "$q.loadingBar",
|
||||
|
||||
"quasarConfOptions": {
|
||||
"propName": "loadingBar",
|
||||
"type": "Object",
|
||||
"tsType": "QLoadingBarOptions",
|
||||
"desc": "QAjaxBar component props, EXCEPT for 'hijack-filter' in quasar.config file (if using Quasar CLI)",
|
||||
"examples": [ "{ position: 'bottom', reverse: true }" ]
|
||||
},
|
||||
|
||||
"props": {
|
||||
"isActive": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is LoadingBar active?",
|
||||
"reactive": true
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"start": {
|
||||
"desc": "Notify bar you've started a background activity",
|
||||
"params": {
|
||||
"speed": {
|
||||
"type": "Number",
|
||||
"desc": "Delay (in milliseconds) between bar progress increments",
|
||||
"default": "300"
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"stop": {
|
||||
"desc": "Notify bar one background activity has finalized",
|
||||
"params": null,
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"increment": {
|
||||
"desc": "Manually trigger a bar progress increment",
|
||||
"params": {
|
||||
"amount": {
|
||||
"type": "Number",
|
||||
"desc": "Amount (0.0 < x < 1.0) to increment with"
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"setDefaults": {
|
||||
"desc": "Set the inner QAjaxBar's props",
|
||||
"params": {
|
||||
"props": {
|
||||
"type": "Object",
|
||||
"tsType": "QLoadingBarOptions",
|
||||
"required": true,
|
||||
"desc": "QAjaxBar component props",
|
||||
"examples": [ "{ position: 'bottom', reverse: true }" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
207
Frontend-Learner/node_modules/quasar/src/plugins/loading/Loading.js
generated
vendored
Normal file
207
Frontend-Learner/node_modules/quasar/src/plugins/loading/Loading.js
generated
vendored
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
import { h, Transition, onMounted } from 'vue'
|
||||
|
||||
import QSpinner from '../../components/spinner/QSpinner.js'
|
||||
|
||||
import { createChildApp } from '../../install-quasar.js'
|
||||
|
||||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
import { createGlobalNode, removeGlobalNode } from '../../utils/private.config/nodes.js'
|
||||
import preventScroll from '../../utils/scroll/prevent-scroll.js'
|
||||
import { isObject } from '../../utils/is/is.js'
|
||||
|
||||
let
|
||||
app,
|
||||
vm,
|
||||
uid = 0,
|
||||
timeout = null,
|
||||
props = {},
|
||||
activeGroups = {}
|
||||
|
||||
const originalDefaults = {
|
||||
group: '__default_quasar_group__',
|
||||
delay: 0,
|
||||
message: false,
|
||||
html: false,
|
||||
spinnerSize: 80,
|
||||
spinnerColor: '',
|
||||
messageColor: '',
|
||||
backgroundColor: '',
|
||||
boxClass: '',
|
||||
spinner: QSpinner,
|
||||
customClass: ''
|
||||
}
|
||||
|
||||
const defaults = { ...originalDefaults }
|
||||
|
||||
function registerProps (opts) {
|
||||
if (opts?.group !== void 0 && activeGroups[ opts.group ] !== void 0) {
|
||||
return Object.assign(activeGroups[ opts.group ], opts)
|
||||
}
|
||||
|
||||
const newProps = isObject(opts) === true && opts.ignoreDefaults === true
|
||||
? { ...originalDefaults, ...opts }
|
||||
: { ...defaults, ...opts }
|
||||
|
||||
activeGroups[ newProps.group ] = newProps
|
||||
return newProps
|
||||
}
|
||||
|
||||
const Plugin = createReactivePlugin({
|
||||
isActive: false
|
||||
}, {
|
||||
show (opts) {
|
||||
if (__QUASAR_SSR_SERVER__) return
|
||||
|
||||
props = registerProps(opts)
|
||||
const { group } = props
|
||||
|
||||
Plugin.isActive = true
|
||||
|
||||
if (app !== void 0) {
|
||||
props.uid = uid
|
||||
vm.$forceUpdate()
|
||||
}
|
||||
else {
|
||||
props.uid = ++uid
|
||||
timeout !== null && clearTimeout(timeout)
|
||||
|
||||
timeout = setTimeout(() => {
|
||||
timeout = null
|
||||
|
||||
const el = createGlobalNode('q-loading')
|
||||
|
||||
app = createChildApp({
|
||||
name: 'QLoading',
|
||||
|
||||
setup () {
|
||||
onMounted(() => {
|
||||
preventScroll(true)
|
||||
})
|
||||
|
||||
function onAfterLeave () {
|
||||
// might be called to finalize
|
||||
// previous leave, even if it was cancelled
|
||||
if (Plugin.isActive !== true && app !== void 0) {
|
||||
preventScroll(false)
|
||||
app.unmount(el)
|
||||
removeGlobalNode(el)
|
||||
app = void 0
|
||||
vm = void 0
|
||||
}
|
||||
}
|
||||
|
||||
function getContent () {
|
||||
if (Plugin.isActive !== true) {
|
||||
return null
|
||||
}
|
||||
|
||||
const content = [
|
||||
h(props.spinner, {
|
||||
class: 'q-loading__spinner',
|
||||
color: props.spinnerColor,
|
||||
size: props.spinnerSize
|
||||
})
|
||||
]
|
||||
|
||||
props.message && content.push(
|
||||
h('div', {
|
||||
class: 'q-loading__message'
|
||||
+ (props.messageColor ? ` text-${ props.messageColor }` : ''),
|
||||
[ props.html === true ? 'innerHTML' : 'textContent' ]: props.message
|
||||
})
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
class: 'q-loading fullscreen flex flex-center z-max ' + props.customClass.trim(),
|
||||
key: props.uid
|
||||
}, [
|
||||
h('div', {
|
||||
class: 'q-loading__backdrop'
|
||||
+ (props.backgroundColor ? ` bg-${ props.backgroundColor }` : '')
|
||||
}),
|
||||
|
||||
h('div', {
|
||||
class: 'q-loading__box column items-center ' + props.boxClass
|
||||
}, content)
|
||||
])
|
||||
}
|
||||
|
||||
return () => h(Transition, {
|
||||
name: 'q-transition--fade',
|
||||
appear: true,
|
||||
onAfterLeave
|
||||
}, getContent)
|
||||
}
|
||||
}, Plugin.__parentApp)
|
||||
|
||||
vm = app.mount(el)
|
||||
}, props.delay)
|
||||
}
|
||||
|
||||
return paramProps => {
|
||||
// if we don't have params (or not an Object param) then we need to hide this group
|
||||
if (paramProps === void 0 || Object(paramProps) !== paramProps) {
|
||||
Plugin.hide(group)
|
||||
return
|
||||
}
|
||||
|
||||
// else we have params so we need to update this group
|
||||
Plugin.show({ ...paramProps, group })
|
||||
}
|
||||
},
|
||||
|
||||
hide (group) {
|
||||
if (__QUASAR_SSR_SERVER__ !== true && Plugin.isActive === true) {
|
||||
if (group === void 0) {
|
||||
// clear out any active groups
|
||||
activeGroups = {}
|
||||
}
|
||||
else if (activeGroups[ group ] === void 0) {
|
||||
// we've already hidden it so nothing to do
|
||||
return
|
||||
}
|
||||
else {
|
||||
// remove active group
|
||||
delete activeGroups[ group ]
|
||||
|
||||
const keys = Object.keys(activeGroups)
|
||||
|
||||
// if there are other groups registered then
|
||||
// show last registered one since that one is still active
|
||||
if (keys.length !== 0) {
|
||||
// get last registered group
|
||||
const lastGroup = keys[ keys.length - 1 ]
|
||||
Plugin.show({ group: lastGroup })
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (timeout !== null) {
|
||||
clearTimeout(timeout)
|
||||
timeout = null
|
||||
}
|
||||
|
||||
Plugin.isActive = false
|
||||
}
|
||||
},
|
||||
|
||||
setDefaults (opts) {
|
||||
if (__QUASAR_SSR_SERVER__ !== true) {
|
||||
isObject(opts) === true && Object.assign(defaults, opts)
|
||||
}
|
||||
},
|
||||
|
||||
install ({ $q, parentApp }) {
|
||||
$q.loading = this
|
||||
|
||||
if (__QUASAR_SSR_SERVER__ !== true) {
|
||||
Plugin.__parentApp = parentApp
|
||||
|
||||
if ($q.config.loading !== void 0) {
|
||||
this.setDefaults($q.config.loading)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default Plugin
|
||||
228
Frontend-Learner/node_modules/quasar/src/plugins/loading/Loading.json
generated
vendored
Normal file
228
Frontend-Learner/node_modules/quasar/src/plugins/loading/Loading.json
generated
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/loading"
|
||||
},
|
||||
|
||||
"injection": "$q.loading",
|
||||
|
||||
"quasarConfOptions": {
|
||||
"propName": "loading",
|
||||
"type": "Object",
|
||||
"definition": {
|
||||
"delay": {
|
||||
"type": "Number",
|
||||
"desc": "Wait a number of millisecond before showing; Not worth showing for 100ms for example then hiding it, so wait until you're sure it's a process that will take some considerable amount of time",
|
||||
"examples": [ "400" ]
|
||||
},
|
||||
"message": {
|
||||
"type": "String",
|
||||
"desc": "Message to display",
|
||||
"examples": [ "'Processing your request'" ]
|
||||
},
|
||||
"group": {
|
||||
"type": "String",
|
||||
"desc": "Default Loading group name",
|
||||
"default": "'__default_quasar_group__'",
|
||||
"examples": [ "'default-group-name'" ],
|
||||
"addedIn": "v2.8"
|
||||
},
|
||||
"html": {
|
||||
"extends": "html",
|
||||
"desc": "Force render the message as HTML; This can lead to XSS attacks so make sure that you sanitize the content"
|
||||
},
|
||||
"boxClass": {
|
||||
"type": "String",
|
||||
"desc": "Content wrapped element custom classes",
|
||||
"examples": [ "'bg-amber text-black'", "'q-pa-xl'" ]
|
||||
},
|
||||
"spinnerSize": {
|
||||
"type": "Number",
|
||||
"desc": "Spinner size (in pixels)"
|
||||
},
|
||||
"spinnerColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for spinner from the Quasar Color Palette"
|
||||
},
|
||||
"messageColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for text from the Quasar Color Palette"
|
||||
},
|
||||
"backgroundColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for background from the Quasar Color Palette"
|
||||
},
|
||||
"spinner": {
|
||||
"type": "Component",
|
||||
"configFileType": "String",
|
||||
"desc": "One of the QSpinners",
|
||||
"examples": [ "QSpinnerAudio" ]
|
||||
},
|
||||
"customClass": {
|
||||
"type": "String",
|
||||
"desc": "Add a CSS class to the container element to easily customize the component",
|
||||
"examples": [ "'my-class'" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"props": {
|
||||
"isActive": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is Loading active?",
|
||||
"reactive": true
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"show": {
|
||||
"desc": "Activate and show",
|
||||
"params": {
|
||||
"opts": {
|
||||
"type": "Object",
|
||||
"tsType": "QLoadingShowOptions",
|
||||
"autoDefineTsType": true,
|
||||
"desc": "All props are optional",
|
||||
"definition": {
|
||||
"delay": {
|
||||
"type": "Number",
|
||||
"desc": "Wait a number of millisecond before showing; Not worth showing for 100ms for example then hiding it, so wait until you're sure it's a process that will take some considerable amount of time"
|
||||
},
|
||||
"message": {
|
||||
"type": "String",
|
||||
"desc": "Message to display",
|
||||
"examples": [ "'Processing your request'" ]
|
||||
},
|
||||
"group": {
|
||||
"type": "String",
|
||||
"desc": "Loading group name",
|
||||
"examples": [ "'some-api-call'" ],
|
||||
"addedIn": "v2.8"
|
||||
},
|
||||
"html": {
|
||||
"extends": "html",
|
||||
"desc": "Render the message as HTML; This can lead to XSS attacks so make sure that you sanitize the message first"
|
||||
},
|
||||
"boxClass": {
|
||||
"type": "String",
|
||||
"desc": "Content wrapped element custom classes",
|
||||
"examples": [ "'bg-amber text-black'", "'q-pa-xl'" ]
|
||||
},
|
||||
"spinnerSize": {
|
||||
"type": "Number",
|
||||
"desc": "Spinner size (in pixels)"
|
||||
},
|
||||
"spinnerColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for spinner from the Quasar Color Palette"
|
||||
},
|
||||
"messageColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for text from the Quasar Color Palette"
|
||||
},
|
||||
"backgroundColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for background from the Quasar Color Palette"
|
||||
},
|
||||
"spinner": {
|
||||
"type": "Component",
|
||||
"desc": "One of the QSpinners"
|
||||
},
|
||||
"customClass": {
|
||||
"type": "String",
|
||||
"desc": "Add a CSS class to easily customize the component",
|
||||
"examples": [ "'my-class'" ]
|
||||
},
|
||||
"ignoreDefaults": {
|
||||
"type": "Boolean",
|
||||
"desc": "Ignore the default configuration (set by setDefaults()) for this instance only"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Function",
|
||||
"desc": "Calling this function with no parameters hides the group; When called with one Object parameter then it updates the Loading group (specified properties are shallow merged with the group ones; note that group cannot be changed while updating and it is ignored)",
|
||||
"params": {
|
||||
"props": {
|
||||
"type": "Object",
|
||||
"tsType": "QLoadingUpdateOptions",
|
||||
"required": false,
|
||||
"desc": "Loading properties that will be shallow merged to the group ones; (See 'opts' param of 'show()' for object properties, except 'group')",
|
||||
"__exemption": [ "definition" ]
|
||||
}
|
||||
},
|
||||
"returns": null,
|
||||
"addedIn": "v2.8"
|
||||
}
|
||||
},
|
||||
|
||||
"hide": {
|
||||
"desc": "Hide it",
|
||||
"params": {
|
||||
"group": {
|
||||
"type": "String",
|
||||
"desc": "Optional Loading group name to hide instead of hiding all groups",
|
||||
"required": false,
|
||||
"examples": [ "'some-api-call'" ],
|
||||
"addedIn": "v2.8"
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"setDefaults": {
|
||||
"desc": "Merge options into the default ones",
|
||||
"params": {
|
||||
"opts": {
|
||||
"type": "Object",
|
||||
"desc": "Pick the subprop you want to define",
|
||||
"required": true,
|
||||
"definition": {
|
||||
"delay": {
|
||||
"type": "Number",
|
||||
"desc": "Wait a number of millisecond before showing; Not worth showing for 100ms for example then hiding it, so wait until you're sure it's a process that will take some considerable amount of time"
|
||||
},
|
||||
"message": {
|
||||
"type": "String",
|
||||
"desc": "Message to display",
|
||||
"examples": [ "'Processing your request'" ]
|
||||
},
|
||||
"group": {
|
||||
"type": "String",
|
||||
"desc": "Default Loading group name",
|
||||
"default": "'__default_quasar_group__'",
|
||||
"examples": [ "'default-group-name'" ],
|
||||
"addedIn": "v2.8"
|
||||
},
|
||||
"spinnerSize": {
|
||||
"type": "Number",
|
||||
"desc": "Spinner size (in pixels)"
|
||||
},
|
||||
"spinnerColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for spinner from the Quasar Color Palette"
|
||||
},
|
||||
"messageColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for text from the Quasar Color Palette"
|
||||
},
|
||||
"backgroundColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for background from the Quasar Color Palette"
|
||||
},
|
||||
"spinner": {
|
||||
"type": "Component",
|
||||
"desc": "One of the QSpinners"
|
||||
},
|
||||
"customClass": {
|
||||
"type": "String",
|
||||
"desc": "Add a CSS class to easily customize the component",
|
||||
"examples": [ "'my-class'" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Frontend-Learner/node_modules/quasar/src/plugins/loading/Loading.sass
generated
vendored
Normal file
26
Frontend-Learner/node_modules/quasar/src/plugins/loading/Loading.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
.q-loading
|
||||
color: #000
|
||||
|
||||
// override q-transition--fade's absolute position
|
||||
position: fixed !important
|
||||
|
||||
&__backdrop
|
||||
position: fixed
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
opacity: .5
|
||||
z-index: -1
|
||||
background-color: #000
|
||||
transition: background-color .28s
|
||||
|
||||
&__box
|
||||
border-radius: $generic-border-radius
|
||||
padding: 18px
|
||||
color: #fff
|
||||
max-width: 450px
|
||||
|
||||
&__message
|
||||
margin: 40px 20px 0
|
||||
text-align: center
|
||||
267
Frontend-Learner/node_modules/quasar/src/plugins/meta/Meta.js
generated
vendored
Normal file
267
Frontend-Learner/node_modules/quasar/src/plugins/meta/Meta.js
generated
vendored
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
import { isRuntimeSsrPreHydration } from '../platform/Platform.js'
|
||||
import extend from '../../utils/extend/extend.js'
|
||||
|
||||
let updateId = null, currentClientMeta
|
||||
export const clientList = []
|
||||
|
||||
function normalize (meta) {
|
||||
if (meta.title) {
|
||||
meta.title = meta.titleTemplate
|
||||
? meta.titleTemplate(meta.title)
|
||||
: meta.title
|
||||
delete meta.titleTemplate
|
||||
}
|
||||
|
||||
;[ [ 'meta', 'content' ], [ 'link', 'href' ] ].forEach(type => {
|
||||
const
|
||||
metaType = meta[ type[ 0 ] ],
|
||||
metaProp = type[ 1 ]
|
||||
|
||||
for (const name in metaType) {
|
||||
const metaLink = metaType[ name ]
|
||||
|
||||
if (metaLink.template) {
|
||||
if (Object.keys(metaLink).length === 1) {
|
||||
delete metaType[ name ]
|
||||
}
|
||||
else {
|
||||
metaLink[ metaProp ] = metaLink.template(metaLink[ metaProp ] || '')
|
||||
delete metaLink.template
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function changed (old, def) {
|
||||
if (Object.keys(old).length !== Object.keys(def).length) {
|
||||
return true
|
||||
}
|
||||
for (const key in old) {
|
||||
if (old[ key ] !== def[ key ]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bodyFilter (name) {
|
||||
return [ 'class', 'style' ].includes(name) === false
|
||||
}
|
||||
|
||||
function htmlFilter (name) {
|
||||
return [ 'lang', 'dir' ].includes(name) === false
|
||||
}
|
||||
|
||||
function diff (meta, other) {
|
||||
const add = {}, remove = {}
|
||||
|
||||
if (meta === void 0) {
|
||||
return { add: other, remove }
|
||||
}
|
||||
|
||||
if (meta.title !== other.title) {
|
||||
add.title = other.title
|
||||
}
|
||||
|
||||
;[ 'meta', 'link', 'script', 'htmlAttr', 'bodyAttr' ].forEach(type => {
|
||||
const old = meta[ type ], cur = other[ type ]
|
||||
remove[ type ] = []
|
||||
|
||||
if (old === void 0 || old === null) {
|
||||
add[ type ] = cur
|
||||
return
|
||||
}
|
||||
|
||||
add[ type ] = {}
|
||||
|
||||
for (const key in old) {
|
||||
if (cur.hasOwnProperty(key) === false) {
|
||||
remove[ type ].push(key)
|
||||
}
|
||||
}
|
||||
for (const key in cur) {
|
||||
if (old.hasOwnProperty(key) === false) {
|
||||
add[ type ][ key ] = cur[ key ]
|
||||
}
|
||||
else if (changed(old[ key ], cur[ key ]) === true) {
|
||||
remove[ type ].push(key)
|
||||
add[ type ][ key ] = cur[ key ]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return { add, remove }
|
||||
}
|
||||
|
||||
function apply ({ add, remove }) {
|
||||
if (add.title) {
|
||||
document.title = add.title
|
||||
}
|
||||
|
||||
if (Object.keys(remove).length !== 0) {
|
||||
[ 'meta', 'link', 'script' ].forEach(type => {
|
||||
remove[ type ].forEach(name => {
|
||||
document.head.querySelector(`${ type }[data-qmeta="${ name }"]`).remove()
|
||||
})
|
||||
})
|
||||
remove.htmlAttr.filter(htmlFilter).forEach(name => {
|
||||
document.documentElement.removeAttribute(name)
|
||||
})
|
||||
remove.bodyAttr.filter(bodyFilter).forEach(name => {
|
||||
document.body.removeAttribute(name)
|
||||
})
|
||||
}
|
||||
|
||||
;[ 'meta', 'link', 'script' ].forEach(type => {
|
||||
const metaType = add[ type ]
|
||||
|
||||
for (const name in metaType) {
|
||||
const tag = document.createElement(type)
|
||||
for (const att in metaType[ name ]) {
|
||||
if (att !== 'innerHTML') {
|
||||
tag.setAttribute(att, metaType[ name ][ att ])
|
||||
}
|
||||
}
|
||||
tag.setAttribute('data-qmeta', name)
|
||||
if (type === 'script') {
|
||||
tag.innerHTML = metaType[ name ].innerHTML || ''
|
||||
}
|
||||
document.head.appendChild(tag)
|
||||
}
|
||||
})
|
||||
Object.keys(add.htmlAttr).filter(htmlFilter).forEach(name => {
|
||||
document.documentElement.setAttribute(name, add.htmlAttr[ name ] || '')
|
||||
})
|
||||
Object.keys(add.bodyAttr).filter(bodyFilter).forEach(name => {
|
||||
document.body.setAttribute(name, add.bodyAttr[ name ] || '')
|
||||
})
|
||||
}
|
||||
|
||||
function getAttr (seed) {
|
||||
return att => {
|
||||
const val = seed[ att ]
|
||||
return att + (val !== true && val !== void 0 ? `="${ val }"` : '')
|
||||
}
|
||||
}
|
||||
|
||||
function getHead (meta) {
|
||||
let output = ''
|
||||
if (meta.title) {
|
||||
output += `<title>${ meta.title }</title>`
|
||||
}
|
||||
;[ 'meta', 'link', 'script' ].forEach(type => {
|
||||
const metaType = meta[ type ]
|
||||
|
||||
for (const att in metaType) {
|
||||
const attrs = Object.keys(metaType[ att ])
|
||||
.filter(att => att !== 'innerHTML')
|
||||
.map(getAttr(metaType[ att ]))
|
||||
|
||||
output += `<${ type } ${ attrs.join(' ') } data-qmeta="${ att }">`
|
||||
if (type === 'script') {
|
||||
output += (metaType[ att ].innerHTML || '') + '</script>'
|
||||
}
|
||||
}
|
||||
})
|
||||
return output
|
||||
}
|
||||
|
||||
function injectServerMeta (ssrContext) {
|
||||
const data = {
|
||||
title: '',
|
||||
titleTemplate: null,
|
||||
meta: {},
|
||||
link: {},
|
||||
htmlAttr: {},
|
||||
bodyAttr: {},
|
||||
noscript: {}
|
||||
}
|
||||
|
||||
const list = ssrContext.__qMetaList
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
extend(true, data, list[ i ])
|
||||
}
|
||||
|
||||
normalize(data)
|
||||
|
||||
const nonce = ssrContext.nonce !== void 0
|
||||
? ` nonce="${ ssrContext.nonce }"`
|
||||
: ''
|
||||
|
||||
const ctx = ssrContext._meta
|
||||
|
||||
const htmlAttr = Object.keys(data.htmlAttr).filter(htmlFilter)
|
||||
|
||||
if (htmlAttr.length !== 0) {
|
||||
ctx.htmlAttrs += (
|
||||
(ctx.htmlAttrs.length !== 0 ? ' ' : '')
|
||||
+ htmlAttr.map(getAttr(data.htmlAttr)).join(' ')
|
||||
)
|
||||
}
|
||||
|
||||
ctx.headTags += getHead(data)
|
||||
|
||||
const bodyAttr = Object.keys(data.bodyAttr).filter(bodyFilter)
|
||||
|
||||
if (bodyAttr.length !== 0) {
|
||||
ctx.bodyAttrs += (
|
||||
(ctx.bodyAttrs.length !== 0 ? ' ' : '')
|
||||
+ bodyAttr.map(getAttr(data.bodyAttr)).join(' ')
|
||||
)
|
||||
}
|
||||
|
||||
ctx.bodyTags += Object.keys(data.noscript)
|
||||
.map(name => `<noscript data-qmeta="${ name }">${ data.noscript[ name ] }</noscript>`)
|
||||
.join('')
|
||||
+ `<script${ nonce } id="qmeta-init">window.__Q_META__=${ delete data.noscript && JSON.stringify(data) }</script>`
|
||||
}
|
||||
|
||||
function updateClientMeta () {
|
||||
updateId = null
|
||||
|
||||
const data = {
|
||||
title: '',
|
||||
titleTemplate: null,
|
||||
meta: {},
|
||||
link: {},
|
||||
script: {},
|
||||
htmlAttr: {},
|
||||
bodyAttr: {}
|
||||
}
|
||||
|
||||
for (let i = 0; i < clientList.length; i++) {
|
||||
const { active, val } = clientList[ i ]
|
||||
|
||||
if (active === true) {
|
||||
extend(true, data, val)
|
||||
}
|
||||
}
|
||||
|
||||
normalize(data)
|
||||
|
||||
apply(diff(currentClientMeta, data))
|
||||
currentClientMeta = data
|
||||
}
|
||||
|
||||
export function planClientUpdate () {
|
||||
updateId !== null && clearTimeout(updateId)
|
||||
updateId = setTimeout(updateClientMeta, 50)
|
||||
}
|
||||
|
||||
export default {
|
||||
install (opts) {
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
const { ssrContext } = opts
|
||||
|
||||
ssrContext.__qMetaList = []
|
||||
ssrContext.onRendered(() => {
|
||||
injectServerMeta(ssrContext)
|
||||
})
|
||||
}
|
||||
else if (this.__installed !== true && isRuntimeSsrPreHydration.value === true) {
|
||||
currentClientMeta = window.__Q_META__
|
||||
document.getElementById('qmeta-init').remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
5
Frontend-Learner/node_modules/quasar/src/plugins/meta/Meta.json
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/plugins/meta/Meta.json
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/meta"
|
||||
}
|
||||
}
|
||||
544
Frontend-Learner/node_modules/quasar/src/plugins/notify/Notify.js
generated
vendored
Normal file
544
Frontend-Learner/node_modules/quasar/src/plugins/notify/Notify.js
generated
vendored
Normal file
|
|
@ -0,0 +1,544 @@
|
|||
import { h, ref, markRaw, TransitionGroup } from 'vue'
|
||||
|
||||
import QAvatar from '../../components/avatar/QAvatar.js'
|
||||
import QIcon from '../../components/icon/QIcon.js'
|
||||
import QBtn from '../../components/btn/QBtn.js'
|
||||
import QSpinner from '../../components/spinner/QSpinner.js'
|
||||
|
||||
import { createChildApp } from '../../install-quasar.js'
|
||||
|
||||
import { createComponent } from '../../utils/private.create/create.js'
|
||||
import { noop } from '../../utils/event/event.js'
|
||||
import { createGlobalNode } from '../../utils/private.config/nodes.js'
|
||||
import { isObject } from '../../utils/is/is.js'
|
||||
|
||||
let uid = 0
|
||||
|
||||
const defaults = {}
|
||||
const groups = {}
|
||||
const notificationsList = {}
|
||||
const positionClass = {}
|
||||
const emptyRE = /^\s*$/
|
||||
const notifRefs = []
|
||||
const invalidTimeoutValues = [ void 0, null, true, false, '' ]
|
||||
|
||||
const positionList = [
|
||||
'top-left', 'top-right',
|
||||
'bottom-left', 'bottom-right',
|
||||
'top', 'bottom', 'left', 'right', 'center'
|
||||
]
|
||||
|
||||
const badgePositions = [
|
||||
'top-left', 'top-right',
|
||||
'bottom-left', 'bottom-right'
|
||||
]
|
||||
|
||||
const notifTypes = {
|
||||
positive: {
|
||||
icon: $q => $q.iconSet.type.positive,
|
||||
color: 'positive'
|
||||
},
|
||||
|
||||
negative: {
|
||||
icon: $q => $q.iconSet.type.negative,
|
||||
color: 'negative'
|
||||
},
|
||||
|
||||
warning: {
|
||||
icon: $q => $q.iconSet.type.warning,
|
||||
color: 'warning',
|
||||
textColor: 'dark'
|
||||
},
|
||||
|
||||
info: {
|
||||
icon: $q => $q.iconSet.type.info,
|
||||
color: 'info'
|
||||
},
|
||||
|
||||
ongoing: {
|
||||
group: false,
|
||||
timeout: 0,
|
||||
spinner: true,
|
||||
color: 'grey-8'
|
||||
}
|
||||
}
|
||||
|
||||
function addNotification (config, $q, originalApi) {
|
||||
if (!config) {
|
||||
return logError('parameter required')
|
||||
}
|
||||
|
||||
let Api
|
||||
const notif = { textColor: 'white' }
|
||||
|
||||
if (config.ignoreDefaults !== true) {
|
||||
Object.assign(notif, defaults)
|
||||
}
|
||||
|
||||
if (isObject(config) === false) {
|
||||
if (notif.type) {
|
||||
Object.assign(notif, notifTypes[ notif.type ])
|
||||
}
|
||||
|
||||
config = { message: config }
|
||||
}
|
||||
|
||||
Object.assign(notif, notifTypes[ config.type || notif.type ], config)
|
||||
|
||||
if (typeof notif.icon === 'function') {
|
||||
notif.icon = notif.icon($q)
|
||||
}
|
||||
|
||||
if (!notif.spinner) {
|
||||
notif.spinner = false
|
||||
}
|
||||
else {
|
||||
if (notif.spinner === true) {
|
||||
notif.spinner = QSpinner
|
||||
}
|
||||
|
||||
notif.spinner = markRaw(notif.spinner)
|
||||
}
|
||||
|
||||
notif.meta = {
|
||||
hasMedia: Boolean(notif.spinner !== false || notif.icon || notif.avatar),
|
||||
hasText: hasContent(notif.message) || hasContent(notif.caption)
|
||||
}
|
||||
|
||||
if (notif.position) {
|
||||
if (positionList.includes(notif.position) === false) {
|
||||
return logError('wrong position', config)
|
||||
}
|
||||
}
|
||||
else {
|
||||
notif.position = 'bottom'
|
||||
}
|
||||
|
||||
if (invalidTimeoutValues.includes(notif.timeout) === true) {
|
||||
notif.timeout = 5000
|
||||
}
|
||||
else {
|
||||
const t = Number(notif.timeout) // we catch exponential notation too with Number() casting
|
||||
if (isNaN(t) || t < 0) {
|
||||
return logError('wrong timeout', config)
|
||||
}
|
||||
notif.timeout = Number.isFinite(t) ? t : 0
|
||||
}
|
||||
|
||||
if (notif.timeout === 0) {
|
||||
notif.progress = false
|
||||
}
|
||||
else if (notif.progress === true) {
|
||||
notif.meta.progressClass = 'q-notification__progress' + (
|
||||
notif.progressClass
|
||||
? ` ${ notif.progressClass }`
|
||||
: ''
|
||||
)
|
||||
|
||||
notif.meta.progressStyle = {
|
||||
animationDuration: `${ notif.timeout + 1000 }ms`
|
||||
}
|
||||
}
|
||||
|
||||
const actions = (
|
||||
Array.isArray(config.actions) === true
|
||||
? config.actions
|
||||
: []
|
||||
).concat(
|
||||
config.ignoreDefaults !== true && Array.isArray(defaults.actions) === true
|
||||
? defaults.actions
|
||||
: []
|
||||
).concat(
|
||||
Array.isArray(notifTypes[ config.type ]?.actions) === true
|
||||
? notifTypes[ config.type ].actions
|
||||
: []
|
||||
)
|
||||
|
||||
const { closeBtn } = notif
|
||||
closeBtn && actions.push({
|
||||
label: typeof closeBtn === 'string'
|
||||
? closeBtn
|
||||
: $q.lang.label.close
|
||||
})
|
||||
|
||||
notif.actions = actions.map(({ handler, noDismiss, ...item }) => ({
|
||||
flat: true,
|
||||
...item,
|
||||
onClick: typeof handler === 'function'
|
||||
? () => {
|
||||
handler()
|
||||
noDismiss !== true && dismiss()
|
||||
}
|
||||
: () => { dismiss() }
|
||||
}))
|
||||
|
||||
if (notif.multiLine === void 0) {
|
||||
notif.multiLine = notif.actions.length > 1
|
||||
}
|
||||
|
||||
Object.assign(notif.meta, {
|
||||
class: 'q-notification row items-stretch'
|
||||
+ ` q-notification--${ notif.multiLine === true ? 'multi-line' : 'standard' }`
|
||||
+ (notif.color !== void 0 ? ` bg-${ notif.color }` : '')
|
||||
+ (notif.textColor !== void 0 ? ` text-${ notif.textColor }` : '')
|
||||
+ (notif.classes !== void 0 ? ` ${ notif.classes }` : ''),
|
||||
|
||||
wrapperClass: 'q-notification__wrapper col relative-position border-radius-inherit '
|
||||
+ (notif.multiLine === true ? 'column no-wrap justify-center' : 'row items-center'),
|
||||
|
||||
contentClass: 'q-notification__content row items-center'
|
||||
+ (notif.multiLine === true ? '' : ' col'),
|
||||
|
||||
leftClass: notif.meta.hasText === true ? 'additional' : 'single',
|
||||
|
||||
attrs: {
|
||||
role: 'alert',
|
||||
...notif.attrs
|
||||
}
|
||||
})
|
||||
|
||||
if (notif.group === false) {
|
||||
notif.group = void 0
|
||||
notif.meta.group = void 0
|
||||
}
|
||||
else {
|
||||
if (notif.group === void 0 || notif.group === true) {
|
||||
// do not replace notifications with different buttons
|
||||
notif.group = [
|
||||
notif.message,
|
||||
notif.caption,
|
||||
notif.multiline
|
||||
].concat(
|
||||
notif.actions.map(props => `${ props.label }*${ props.icon }`)
|
||||
).join('|')
|
||||
}
|
||||
|
||||
notif.meta.group = notif.group + '|' + notif.position
|
||||
}
|
||||
|
||||
if (notif.actions.length === 0) {
|
||||
notif.actions = void 0
|
||||
}
|
||||
else {
|
||||
notif.meta.actionsClass = 'q-notification__actions row items-center '
|
||||
+ (notif.multiLine === true ? 'justify-end' : 'col-auto')
|
||||
+ (notif.meta.hasMedia === true ? ' q-notification__actions--with-media' : '')
|
||||
}
|
||||
|
||||
if (originalApi !== void 0) {
|
||||
// reset timeout if any
|
||||
if (originalApi.notif.meta.timer) {
|
||||
clearTimeout(originalApi.notif.meta.timer)
|
||||
originalApi.notif.meta.timer = void 0
|
||||
}
|
||||
|
||||
// retain uid
|
||||
notif.meta.uid = originalApi.notif.meta.uid
|
||||
|
||||
// replace notif
|
||||
const index = notificationsList[ notif.position ].value.indexOf(originalApi.notif)
|
||||
notificationsList[ notif.position ].value[ index ] = notif
|
||||
}
|
||||
else {
|
||||
const original = groups[ notif.meta.group ]
|
||||
|
||||
// woohoo, it's a new notification
|
||||
if (original === void 0) {
|
||||
notif.meta.uid = uid++
|
||||
notif.meta.badge = 1
|
||||
|
||||
if ([ 'left', 'right', 'center' ].indexOf(notif.position) !== -1) {
|
||||
notificationsList[ notif.position ].value.splice(
|
||||
Math.floor(notificationsList[ notif.position ].value.length / 2),
|
||||
0,
|
||||
notif
|
||||
)
|
||||
}
|
||||
else {
|
||||
const action = notif.position.indexOf('top') !== -1 ? 'unshift' : 'push'
|
||||
notificationsList[ notif.position ].value[ action ](notif)
|
||||
}
|
||||
|
||||
if (notif.group !== void 0) {
|
||||
groups[ notif.meta.group ] = notif
|
||||
}
|
||||
}
|
||||
// ok, so it's NOT a new one
|
||||
else {
|
||||
// reset timeout if any
|
||||
if (original.meta.timer) {
|
||||
clearTimeout(original.meta.timer)
|
||||
original.meta.timer = void 0
|
||||
}
|
||||
|
||||
if (notif.badgePosition !== void 0) {
|
||||
if (badgePositions.includes(notif.badgePosition) === false) {
|
||||
return logError('wrong badgePosition', config)
|
||||
}
|
||||
}
|
||||
else {
|
||||
notif.badgePosition = `top-${ notif.position.indexOf('left') !== -1 ? 'right' : 'left' }`
|
||||
}
|
||||
|
||||
notif.meta.uid = original.meta.uid
|
||||
notif.meta.badge = original.meta.badge + 1
|
||||
notif.meta.badgeClass = `q-notification__badge q-notification__badge--${ notif.badgePosition }`
|
||||
+ (notif.badgeColor !== void 0 ? ` bg-${ notif.badgeColor }` : '')
|
||||
+ (notif.badgeTextColor !== void 0 ? ` text-${ notif.badgeTextColor }` : '')
|
||||
+ (notif.badgeClass ? ` ${ notif.badgeClass }` : '')
|
||||
|
||||
const index = notificationsList[ notif.position ].value.indexOf(original)
|
||||
notificationsList[ notif.position ].value[ index ] = groups[ notif.meta.group ] = notif
|
||||
}
|
||||
}
|
||||
|
||||
const dismiss = () => {
|
||||
removeNotification(notif)
|
||||
Api = void 0
|
||||
}
|
||||
|
||||
if (notif.timeout > 0) {
|
||||
notif.meta.timer = setTimeout(() => {
|
||||
notif.meta.timer = void 0
|
||||
dismiss()
|
||||
}, notif.timeout + /* show duration */ 1000)
|
||||
}
|
||||
|
||||
// only non-groupable can be updated
|
||||
if (notif.group !== void 0) {
|
||||
return props => {
|
||||
if (props !== void 0) {
|
||||
logError('trying to update a grouped one which is forbidden', config)
|
||||
}
|
||||
else {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Api = {
|
||||
dismiss,
|
||||
config,
|
||||
notif
|
||||
}
|
||||
|
||||
if (originalApi !== void 0) {
|
||||
Object.assign(originalApi, Api)
|
||||
return
|
||||
}
|
||||
|
||||
return props => {
|
||||
// if notification wasn't previously dismissed
|
||||
if (Api !== void 0) {
|
||||
// if no params, then we must dismiss the notification
|
||||
if (props === void 0) {
|
||||
Api.dismiss()
|
||||
}
|
||||
// otherwise we're updating it
|
||||
else {
|
||||
const newNotif = Object.assign({}, Api.config, props, {
|
||||
group: false,
|
||||
position: notif.position
|
||||
})
|
||||
|
||||
addNotification(newNotif, $q, Api)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeNotification (notif) {
|
||||
if (notif.meta.timer) {
|
||||
clearTimeout(notif.meta.timer)
|
||||
notif.meta.timer = void 0
|
||||
}
|
||||
|
||||
const index = notificationsList[ notif.position ].value.indexOf(notif)
|
||||
if (index !== -1) {
|
||||
if (notif.group !== void 0) {
|
||||
delete groups[ notif.meta.group ]
|
||||
}
|
||||
|
||||
const el = notifRefs[ '' + notif.meta.uid ]
|
||||
|
||||
if (el) {
|
||||
const { width, height } = getComputedStyle(el)
|
||||
|
||||
el.style.left = `${ el.offsetLeft }px`
|
||||
el.style.width = width
|
||||
el.style.height = height
|
||||
}
|
||||
|
||||
notificationsList[ notif.position ].value.splice(index, 1)
|
||||
|
||||
if (typeof notif.onDismiss === 'function') {
|
||||
notif.onDismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hasContent (str) {
|
||||
return str !== void 0
|
||||
&& str !== null
|
||||
&& emptyRE.test(str) !== true
|
||||
}
|
||||
|
||||
function logError (error, config) {
|
||||
console.error(`Notify: ${ error }`, config)
|
||||
return false
|
||||
}
|
||||
|
||||
function getComponent () {
|
||||
return createComponent({
|
||||
name: 'QNotifications',
|
||||
|
||||
// hide App from Vue devtools
|
||||
devtools: { hide: true },
|
||||
|
||||
setup () {
|
||||
return () => h('div', { class: 'q-notifications' }, positionList.map(pos => {
|
||||
return h(TransitionGroup, {
|
||||
key: pos,
|
||||
class: positionClass[ pos ],
|
||||
tag: 'div',
|
||||
name: `q-notification--${ pos }`
|
||||
}, () => notificationsList[ pos ].value.map(notif => {
|
||||
const meta = notif.meta
|
||||
const mainChild = []
|
||||
|
||||
if (meta.hasMedia === true) {
|
||||
if (notif.spinner !== false) {
|
||||
mainChild.push(
|
||||
h(notif.spinner, {
|
||||
class: 'q-notification__spinner q-notification__spinner--' + meta.leftClass,
|
||||
color: notif.spinnerColor,
|
||||
size: notif.spinnerSize
|
||||
})
|
||||
)
|
||||
}
|
||||
else if (notif.icon) {
|
||||
mainChild.push(
|
||||
h(QIcon, {
|
||||
class: 'q-notification__icon q-notification__icon--' + meta.leftClass,
|
||||
name: notif.icon,
|
||||
color: notif.iconColor,
|
||||
size: notif.iconSize,
|
||||
role: 'img'
|
||||
})
|
||||
)
|
||||
}
|
||||
else if (notif.avatar) {
|
||||
mainChild.push(
|
||||
h(QAvatar, {
|
||||
class: 'q-notification__avatar q-notification__avatar--' + meta.leftClass
|
||||
}, () => h('img', { src: notif.avatar, 'aria-hidden': 'true' }))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (meta.hasText === true) {
|
||||
let msgChild
|
||||
const msgData = { class: 'q-notification__message col' }
|
||||
|
||||
if (notif.html === true) {
|
||||
msgData.innerHTML = notif.caption
|
||||
? `<div>${ notif.message }</div><div class="q-notification__caption">${ notif.caption }</div>`
|
||||
: notif.message
|
||||
}
|
||||
else {
|
||||
const msgNode = [ notif.message ]
|
||||
msgChild = notif.caption
|
||||
? [
|
||||
h('div', msgNode),
|
||||
h('div', { class: 'q-notification__caption' }, [ notif.caption ])
|
||||
]
|
||||
: msgNode
|
||||
}
|
||||
|
||||
mainChild.push(
|
||||
h('div', msgData, msgChild)
|
||||
)
|
||||
}
|
||||
|
||||
const child = [
|
||||
h('div', { class: meta.contentClass }, mainChild)
|
||||
]
|
||||
|
||||
notif.progress === true && child.push(
|
||||
h('div', {
|
||||
key: `${ meta.uid }|p|${ meta.badge }`,
|
||||
class: meta.progressClass,
|
||||
style: meta.progressStyle
|
||||
})
|
||||
)
|
||||
|
||||
notif.actions !== void 0 && child.push(
|
||||
h('div', {
|
||||
class: meta.actionsClass
|
||||
}, notif.actions.map(props => h(QBtn, props)))
|
||||
)
|
||||
|
||||
meta.badge > 1 && child.push(
|
||||
h('div', {
|
||||
key: `${ meta.uid }|${ meta.badge }`,
|
||||
class: notif.meta.badgeClass,
|
||||
style: notif.badgeStyle
|
||||
}, [ meta.badge ])
|
||||
)
|
||||
|
||||
return h('div', {
|
||||
ref: el => { notifRefs[ '' + meta.uid ] = el },
|
||||
key: meta.uid,
|
||||
class: meta.class,
|
||||
...meta.attrs
|
||||
}, [
|
||||
h('div', { class: meta.wrapperClass }, child)
|
||||
])
|
||||
}))
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
setDefaults (opts) {
|
||||
if (__QUASAR_SSR_SERVER__ !== true) {
|
||||
isObject(opts) === true && Object.assign(defaults, opts)
|
||||
}
|
||||
},
|
||||
|
||||
registerType (typeName, typeOpts) {
|
||||
if (__QUASAR_SSR_SERVER__ !== true && isObject(typeOpts) === true) {
|
||||
notifTypes[ typeName ] = typeOpts
|
||||
}
|
||||
},
|
||||
|
||||
install ({ $q, parentApp }) {
|
||||
$q.notify = this.create = __QUASAR_SSR_SERVER__
|
||||
? noop
|
||||
: opts => addNotification(opts, $q)
|
||||
|
||||
$q.notify.setDefaults = this.setDefaults
|
||||
$q.notify.registerType = this.registerType
|
||||
|
||||
if ($q.config.notify !== void 0) {
|
||||
this.setDefaults($q.config.notify)
|
||||
}
|
||||
|
||||
if (__QUASAR_SSR_SERVER__ !== true && this.__installed !== true) {
|
||||
positionList.forEach(pos => {
|
||||
notificationsList[ pos ] = ref([])
|
||||
|
||||
const
|
||||
vert = [ 'left', 'center', 'right' ].includes(pos) === true ? 'center' : (pos.indexOf('top') !== -1 ? 'top' : 'bottom'),
|
||||
align = pos.indexOf('left') !== -1 ? 'start' : (pos.indexOf('right') !== -1 ? 'end' : 'center'),
|
||||
classes = [ 'left', 'right' ].includes(pos) ? `items-${ pos === 'left' ? 'start' : 'end' } justify-center` : (pos === 'center' ? 'flex-center' : `items-${ align }`)
|
||||
|
||||
positionClass[ pos ] = `q-notifications__list q-notifications__list--${ vert } fixed column no-wrap ${ classes }`
|
||||
})
|
||||
|
||||
const el = createGlobalNode('q-notify')
|
||||
createChildApp(getComponent(), parentApp).mount(el)
|
||||
}
|
||||
}
|
||||
}
|
||||
492
Frontend-Learner/node_modules/quasar/src/plugins/notify/Notify.json
generated
vendored
Normal file
492
Frontend-Learner/node_modules/quasar/src/plugins/notify/Notify.json
generated
vendored
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/notify"
|
||||
},
|
||||
|
||||
"injection": "$q.notify",
|
||||
|
||||
"quasarConfOptions": {
|
||||
"propName": "notify",
|
||||
"type": "Object",
|
||||
"definition": {
|
||||
"type": {
|
||||
"type": "String",
|
||||
"desc": "Optional type (that has been previously registered) or one of the out of the box ones ('positive', 'negative', 'warning', 'info', 'ongoing')",
|
||||
"examples": [ "'negative'", "'custom-type'" ]
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"textColor": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"message": {
|
||||
"type": "String",
|
||||
"desc": "The content of your message",
|
||||
"examples": [ "'John Doe pinged you'" ]
|
||||
},
|
||||
|
||||
"caption": {
|
||||
"type": "String",
|
||||
"desc": "The content of your optional caption",
|
||||
"examples": [ "'5 minutes ago'" ]
|
||||
},
|
||||
|
||||
"html": {
|
||||
"type": "Boolean",
|
||||
"desc": "Render the message as HTML; This can lead to XSS attacks, so make sure that you sanitize the message first"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"iconColor": {
|
||||
"extends": "color",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"iconSize": {
|
||||
"extends": "size",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"avatar": {
|
||||
"type": "String",
|
||||
"desc": "URL to an avatar/image; Suggestion: use public folder",
|
||||
"examples": [
|
||||
"# (public folder) 'img/something.png'",
|
||||
"# (relative path format) require('./my_img.jpg')",
|
||||
"# (URL) https://some-site.net/some-img.gif"
|
||||
]
|
||||
},
|
||||
|
||||
"spinner": {
|
||||
"type": [ "Boolean", "Component" ],
|
||||
"configFileType": [ "Boolean", "String" ],
|
||||
"desc": "Useful for notifications that are updated; Displays a Quasar spinner instead of an avatar or icon; If value is Boolean 'true' then the default QSpinner is shown",
|
||||
"examples": [ "true", "QSpinnerBars" ]
|
||||
},
|
||||
|
||||
"spinnerColor": {
|
||||
"extends": "color",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"spinnerSize": {
|
||||
"extends": "size",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"position": {
|
||||
"type": "String",
|
||||
"desc": "Window side/corner to stick to",
|
||||
"default": "'bottom'",
|
||||
"values": [
|
||||
"'top-left'", "'top-right'",
|
||||
"'bottom-left'", "'bottom-right'",
|
||||
"'top'", "'bottom'", "'left'", "'right'", "'center'"
|
||||
]
|
||||
},
|
||||
|
||||
"group": {
|
||||
"type": [ "Boolean", "String", "Number" ],
|
||||
"desc": "Override the auto generated group with custom one; Grouped notifications cannot be updated; String or number value inform this is part of a specific group, regardless of its options; When a new notification is triggered with same group name, it replaces the old one and shows a badge with how many times the notification was triggered",
|
||||
"default": "# message + caption + multiline + actions labels + position",
|
||||
"examples": [ "'my-group'" ]
|
||||
},
|
||||
|
||||
"badgeColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for the badge from the Quasar Color Palette"
|
||||
},
|
||||
"badgeTextColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for the badge text from the Quasar Color Palette"
|
||||
},
|
||||
"badgePosition": {
|
||||
"type": "String",
|
||||
"desc": "Notification corner to stick badge to; If notification is on the left side then default is top-right otherwise it is top-left",
|
||||
"default": "# top-left/top-right",
|
||||
"values": [
|
||||
"'top-left'", "'top-right'",
|
||||
"'bottom-left'", "'bottom-right'"
|
||||
]
|
||||
},
|
||||
"badgeStyle": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueStyleProp",
|
||||
"desc": "Style definitions to be attributed to the badge",
|
||||
"examples": [
|
||||
"'background-color: #ff0000'",
|
||||
"{ backgroundColor: '#ff0000' }"
|
||||
]
|
||||
},
|
||||
"badgeClass": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueClassProp",
|
||||
"desc": "Class definitions to be attributed to the badge",
|
||||
"examples": [
|
||||
"'my-special-class'",
|
||||
"{ 'my-special-class': true }"
|
||||
]
|
||||
},
|
||||
|
||||
"progress": {
|
||||
"type": "Boolean",
|
||||
"desc": "Show progress bar to detail when notification will disappear automatically (unless timeout is 0)"
|
||||
},
|
||||
"progressClass": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueClassProp",
|
||||
"desc": "Class definitions to be attributed to the progress bar",
|
||||
"examples": [
|
||||
"'my-special-class'",
|
||||
"{ 'my-special-class': true }"
|
||||
]
|
||||
},
|
||||
|
||||
"classes": {
|
||||
"type": "String",
|
||||
"desc": "Add CSS class(es) to the notification for easier customization",
|
||||
"examples": [ "'my-notif-class'" ]
|
||||
},
|
||||
|
||||
"attrs": {
|
||||
"type": "Object",
|
||||
"desc": "Key-value for attributes to be set on the notification",
|
||||
"examples": [ "{ role: 'alertdialog' }" ],
|
||||
"__exemption": [ "definition" ]
|
||||
},
|
||||
|
||||
"timeout": {
|
||||
"type": "Number",
|
||||
"desc": "Amount of time to display (in milliseconds). Set to 0 to never dismiss automatically.",
|
||||
"default": "5000"
|
||||
},
|
||||
|
||||
"actions": {
|
||||
"type": "Array",
|
||||
"tsType": "QNotifyAction",
|
||||
"desc": "Notification actions (buttons); Unless 'noDismiss' is true, clicking/tapping on the button will close the notification; Also check 'closeBtn' convenience prop",
|
||||
"definition": {
|
||||
"handler": {
|
||||
"type": "Function",
|
||||
"configFileType": null,
|
||||
"desc": "Function to be executed when the button is clicked/tapped",
|
||||
"params": null,
|
||||
"returns": null,
|
||||
"examples": [ "() => { console.log('button clicked') }" ]
|
||||
},
|
||||
"noDismiss": {
|
||||
"type": "Boolean",
|
||||
"desc": "Do not dismiss the notification when the button is clicked/tapped"
|
||||
},
|
||||
"...": {
|
||||
"type": "Any",
|
||||
"desc": "Any other QBtn prop except 'onClick' (use 'handler' instead, only possible with UI config)",
|
||||
"examples": [ "label: 'Learn more'", "color: 'primary'" ]
|
||||
}
|
||||
},
|
||||
"examples": [ "[ { label: 'Show', handler: () => {}, 'aria-label': 'Button label' }, { icon: 'map', handler: () => {}, color: 'yellow' }, { label: 'Learn more', noDismiss: true, handler: () => {} } ]" ]
|
||||
},
|
||||
|
||||
"onDismiss": {
|
||||
"type": "Function",
|
||||
"configFileType": null,
|
||||
"desc": "Function to call when notification gets dismissed",
|
||||
"params": null,
|
||||
"returns": null,
|
||||
"examples": [ "() => { console.log('Dismissed') }" ]
|
||||
},
|
||||
|
||||
"closeBtn": {
|
||||
"type": [ "Boolean", "String" ],
|
||||
"desc": "Convenient way to add a dismiss button with a specific label, without using the 'actions' prop; If set to true, it uses a label according to the current Quasar language",
|
||||
"examples": [ "'Close me'" ]
|
||||
},
|
||||
|
||||
"multiLine": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put notification into multi-line mode; If this prop isn't used and more than one 'action' is specified then notification goes into multi-line mode by default"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"create": {
|
||||
"tsInjectionPoint": true,
|
||||
"desc": "Creates a notification; Same as calling $q.notify(...)",
|
||||
"params": {
|
||||
"opts": {
|
||||
"type": [ "Object", "String" ],
|
||||
"tsType": "QNotifyCreateOptions",
|
||||
"autoDefineTsType": true,
|
||||
"required": true,
|
||||
"desc": "Notification options",
|
||||
"definition": {
|
||||
"type": {
|
||||
"type": "String",
|
||||
"desc": "Optional type (that has been previously registered) or one of the out of the box ones ('positive', 'negative', 'warning', 'info', 'ongoing')",
|
||||
"examples": [ "'negative'", "'custom-type'" ]
|
||||
},
|
||||
|
||||
"color": {
|
||||
"extends": "color"
|
||||
},
|
||||
|
||||
"textColor": {
|
||||
"extends": "text-color"
|
||||
},
|
||||
|
||||
"message": {
|
||||
"type": "String",
|
||||
"desc": "The content of your message",
|
||||
"examples": [ "'John Doe pinged you'" ]
|
||||
},
|
||||
|
||||
"caption": {
|
||||
"type": "String",
|
||||
"desc": "The content of your optional caption",
|
||||
"examples": [ "'5 minutes ago'" ]
|
||||
},
|
||||
|
||||
"html": {
|
||||
"type": "Boolean",
|
||||
"desc": "Render the message as HTML; This can lead to XSS attacks, so make sure that you sanitize the message first"
|
||||
},
|
||||
|
||||
"icon": {
|
||||
"extends": "icon"
|
||||
},
|
||||
|
||||
"iconColor": {
|
||||
"extends": "color",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"iconSize": {
|
||||
"extends": "size",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"avatar": {
|
||||
"type": "String",
|
||||
"desc": "URL to an avatar/image; Suggestion: use public folder",
|
||||
"examples": [
|
||||
"# (public folder) 'img/something.png'",
|
||||
"# (relative path format) require('./my_img.jpg')",
|
||||
"# (URL) https://some-site.net/some-img.gif"
|
||||
]
|
||||
},
|
||||
|
||||
"spinner": {
|
||||
"type": [ "Boolean", "Component" ],
|
||||
"desc": "Useful for notifications that are updated; Displays a Quasar spinner instead of an avatar or icon; If value is Boolean 'true' then the default QSpinner is shown",
|
||||
"examples": [ "true", "QSpinnerBars" ]
|
||||
},
|
||||
|
||||
"spinnerColor": {
|
||||
"extends": "color",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"spinnerSize": {
|
||||
"extends": "size",
|
||||
"addedIn": "v2.5.5"
|
||||
},
|
||||
|
||||
"position": {
|
||||
"type": "String",
|
||||
"desc": "Window side/corner to stick to",
|
||||
"default": "'bottom'",
|
||||
"values": [
|
||||
"'top-left'", "'top-right'",
|
||||
"'bottom-left'", "'bottom-right'",
|
||||
"'top'", "'bottom'", "'left'", "'right'", "'center'"
|
||||
]
|
||||
},
|
||||
|
||||
"group": {
|
||||
"type": [ "Boolean", "String", "Number" ],
|
||||
"desc": "Override the auto generated group with custom one; Grouped notifications cannot be updated; String or number value inform this is part of a specific group, regardless of its options; When a new notification is triggered with same group name, it replaces the old one and shows a badge with how many times the notification was triggered",
|
||||
"default": "# message + caption + multiline + actions labels + position",
|
||||
"examples": [ "'my-group'" ]
|
||||
},
|
||||
|
||||
"badgeColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for the badge from the Quasar Color Palette"
|
||||
},
|
||||
"badgeTextColor": {
|
||||
"extends": "color",
|
||||
"desc": "Color name for the badge text from the Quasar Color Palette"
|
||||
},
|
||||
"badgePosition": {
|
||||
"type": "String",
|
||||
"desc": "Notification corner to stick badge to; If notification is on the left side then default is top-right otherwise it is top-left",
|
||||
"default": "# top-left/top-right",
|
||||
"values": [
|
||||
"'top-left'", "'top-right'",
|
||||
"'bottom-left'", "'bottom-right'"
|
||||
]
|
||||
},
|
||||
"badgeStyle": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueStyleProp",
|
||||
"desc": "Style definitions to be attributed to the badge",
|
||||
"examples": [
|
||||
"'background-color: #ff0000'",
|
||||
"{ backgroundColor: '#ff0000' }"
|
||||
]
|
||||
},
|
||||
"badgeClass": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueClassProp",
|
||||
"desc": "Class definitions to be attributed to the badge",
|
||||
"examples": [
|
||||
"'my-special-class'",
|
||||
"{ 'my-special-class': true }"
|
||||
]
|
||||
},
|
||||
|
||||
"progress": {
|
||||
"type": "Boolean",
|
||||
"desc": "Show progress bar to detail when notification will disappear automatically (unless timeout is 0)"
|
||||
},
|
||||
"progressClass": {
|
||||
"type": [ "String", "Array", "Object" ],
|
||||
"tsType": "VueClassProp",
|
||||
"desc": "Class definitions to be attributed to the progress bar",
|
||||
"examples": [
|
||||
"'my-special-class'",
|
||||
"{ 'my-special-class': true }"
|
||||
]
|
||||
},
|
||||
|
||||
"classes": {
|
||||
"type": "String",
|
||||
"desc": "Add CSS class(es) to the notification for easier customization",
|
||||
"examples": [ "'my-notif-class'" ]
|
||||
},
|
||||
|
||||
"attrs": {
|
||||
"type": "Object",
|
||||
"desc": "Key-value for attributes to be set on the notification",
|
||||
"examples": [ "{ role: 'alertdialog' }" ],
|
||||
"__exemption": [ "definition" ]
|
||||
},
|
||||
|
||||
"timeout": {
|
||||
"type": "Number",
|
||||
"desc": "Amount of time to display (in milliseconds). Set to 0 to never dismiss automatically.",
|
||||
"default": "5000",
|
||||
"examples": [ "2500" ]
|
||||
},
|
||||
|
||||
"actions": {
|
||||
"type": "Array",
|
||||
"tsType": "QNotifyAction",
|
||||
"desc": "Notification actions (buttons); Unless 'noDismiss' is true, clicking/tapping on the button will close the notification; Also check 'closeBtn' convenience prop",
|
||||
"definition": {
|
||||
"handler": {
|
||||
"type": "Function",
|
||||
"desc": "Function to be executed when the button is clicked/tapped",
|
||||
"params": null,
|
||||
"returns": null,
|
||||
"examples": [ "() => { console.log('button clicked') }" ]
|
||||
},
|
||||
"noDismiss": {
|
||||
"type": "Boolean",
|
||||
"desc": "Do not dismiss the notification when the button is clicked/tapped"
|
||||
},
|
||||
"...": {
|
||||
"type": "Any",
|
||||
"desc": "Any other QBtn prop except 'onClick' (use 'handler' instead)",
|
||||
"examples": [ "label: 'Learn more'", "color: 'primary'" ]
|
||||
}
|
||||
},
|
||||
"examples": [ "[ { label: 'Show', handler: () => {}, 'aria-label': 'Button label' }, { icon: 'map', handler: () => {}, color: 'yellow' }, { label: 'Learn more', noDismiss: true, handler: () => {} } ]" ]
|
||||
},
|
||||
|
||||
"onDismiss": {
|
||||
"type": "Function",
|
||||
"desc": "Function to call when notification gets dismissed",
|
||||
"params": null,
|
||||
"returns": null,
|
||||
"examples": [ "() => { console.log('Dismissed') }" ]
|
||||
},
|
||||
|
||||
"closeBtn": {
|
||||
"type": [ "Boolean", "String" ],
|
||||
"desc": "Convenient way to add a dismiss button with a specific label, without using the 'actions' prop; If set to true, it uses a label according to the current Quasar language",
|
||||
"examples": [ "'Close me'" ]
|
||||
},
|
||||
|
||||
"multiLine": {
|
||||
"type": "Boolean",
|
||||
"desc": "Put notification into multi-line mode; If this prop isn't used and more than one 'action' is specified then notification goes into multi-line mode by default"
|
||||
},
|
||||
|
||||
"ignoreDefaults": {
|
||||
"type": "Boolean",
|
||||
"desc": "Ignore the default configuration (set by setDefaults()) for this instance only"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Function",
|
||||
"desc": "Calling this function with no parameters hides the notification; When called with one Object parameter (the original notification must NOT be grouped), it updates the notification (specified properties are shallow merged with previous ones; note that group and position cannot be changed while updating and so they are ignored)",
|
||||
"params": {
|
||||
"props": {
|
||||
"type": "Object",
|
||||
"tsType": "QNotifyUpdateOptions",
|
||||
"required": false,
|
||||
"desc": "Notification properties that will be shallow merged to previous ones in order to update the non-grouped notification; (See 'opts' param of 'create()' for object properties, except 'group' and 'position')",
|
||||
"__exemption": [ "definition" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
},
|
||||
|
||||
"setDefaults": {
|
||||
"desc": "Merge options into the default ones",
|
||||
"params": {
|
||||
"opts": {
|
||||
"type": "Object",
|
||||
"tsType": "QNotifyOptions",
|
||||
"required": true,
|
||||
"desc": "Notification options except 'ignoreDefaults' (See 'opts' param of 'create()' for object properties)",
|
||||
"__exemption": [ "definition" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"registerType": {
|
||||
"desc": "Register a new type of notification (or override an existing one)",
|
||||
"params": {
|
||||
"typeName": {
|
||||
"type": "String",
|
||||
"required": true,
|
||||
"desc": "Name of the type (to be used as 'type' prop later on)",
|
||||
"examples": [ "'my-type'" ]
|
||||
},
|
||||
|
||||
"typeOpts": {
|
||||
"type": "Object",
|
||||
"tsType": "QNotifyOptions",
|
||||
"required": true,
|
||||
"desc": "Notification options except 'ignoreDefaults' (See 'opts' param of 'create()' for object properties)",
|
||||
"__exemption": [ "definition" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
206
Frontend-Learner/node_modules/quasar/src/plugins/notify/Notify.sass
generated
vendored
Normal file
206
Frontend-Learner/node_modules/quasar/src/plugins/notify/Notify.sass
generated
vendored
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
.q-notifications__list
|
||||
z-index: $z-notify
|
||||
pointer-events: none
|
||||
left: 0
|
||||
right: 0
|
||||
margin-bottom: 10px
|
||||
position: relative
|
||||
|
||||
&--center
|
||||
top: 0
|
||||
bottom: 0
|
||||
&--top
|
||||
top: 0
|
||||
&--bottom
|
||||
bottom: 0
|
||||
|
||||
body.q-ios-padding .q-notifications__list
|
||||
&--center, &--top
|
||||
top: $ios-statusbar-height
|
||||
top: env(safe-area-inset-top)
|
||||
&--center, &--bottom
|
||||
bottom: env(safe-area-inset-bottom)
|
||||
|
||||
.q-notification
|
||||
box-shadow: $shadow-2
|
||||
border-radius: $generic-border-radius
|
||||
pointer-events: all
|
||||
display: inline-flex
|
||||
margin: 10px 10px 0
|
||||
transition: transform 1s, opacity 1s
|
||||
z-index: $z-notify
|
||||
flex-shrink: 0
|
||||
|
||||
max-width: 95vw
|
||||
|
||||
background: #323232
|
||||
color: #fff
|
||||
|
||||
font-size: 14px
|
||||
|
||||
&__icon
|
||||
font-size: 24px
|
||||
flex: 0 0 1em
|
||||
&--additional
|
||||
margin-right: 16px
|
||||
|
||||
&__avatar
|
||||
font-size: 32px
|
||||
&--additional
|
||||
margin-right: 8px
|
||||
|
||||
&__spinner
|
||||
font-size: 32px
|
||||
&--additional
|
||||
margin-right: 8px
|
||||
|
||||
&__message
|
||||
padding: 8px 0
|
||||
|
||||
&__caption
|
||||
font-size: 0.9em
|
||||
opacity: 0.7
|
||||
|
||||
&__actions
|
||||
color: var(--q-primary)
|
||||
|
||||
&__badge
|
||||
animation: q-notif-badge .42s
|
||||
padding: 4px 8px
|
||||
position: absolute
|
||||
box-shadow: $shadow-1
|
||||
background-color: var(--q-negative)
|
||||
color: #fff
|
||||
border-radius: $generic-border-radius
|
||||
font-size: 12px
|
||||
line-height: 12px
|
||||
|
||||
&--top-left,
|
||||
&--top-right
|
||||
top: -6px
|
||||
|
||||
&--bottom-left,
|
||||
&--bottom-right
|
||||
bottom: -6px
|
||||
|
||||
&--top-left,
|
||||
&--bottom-left
|
||||
left: -22px
|
||||
|
||||
&--top-right,
|
||||
&--bottom-right
|
||||
right: -22px
|
||||
|
||||
&__progress
|
||||
z-index: -1
|
||||
position: absolute
|
||||
height: 3px
|
||||
bottom: 0
|
||||
left: -10px
|
||||
right: -10px
|
||||
animation: q-notif-progress linear
|
||||
background: currentColor
|
||||
opacity: .3
|
||||
border-radius: $generic-border-radius $generic-border-radius 0 0
|
||||
transform-origin: 0 50%
|
||||
transform: scaleX(0)
|
||||
|
||||
&--standard
|
||||
padding: 0 16px
|
||||
min-height: 48px
|
||||
|
||||
.q-notification__actions
|
||||
padding: 6px 0 6px 8px
|
||||
margin-right: -8px
|
||||
|
||||
&--multi-line
|
||||
min-height: 68px
|
||||
padding: 8px 16px
|
||||
|
||||
.q-notification__badge
|
||||
&--top-left,
|
||||
&--top-right
|
||||
top: -15px
|
||||
|
||||
&--bottom-left,
|
||||
&--bottom-right
|
||||
bottom: -15px
|
||||
|
||||
.q-notification__progress
|
||||
bottom: -8px
|
||||
|
||||
.q-notification__actions
|
||||
padding: 0
|
||||
|
||||
&--with-media
|
||||
padding-left: 25px
|
||||
|
||||
&--top-left-enter-from, &--top-left-leave-to,
|
||||
&--top-enter-from, &--top-leave-to,
|
||||
&--top-right-enter-from, &--top-right-leave-to
|
||||
opacity: 0
|
||||
transform: translateY(-50px)
|
||||
z-index: ($z-notify - 1)
|
||||
|
||||
&--left-enter-from, &--left-leave-to,
|
||||
&--center-enter-from, &--center-leave-to,
|
||||
&--right-enter-from, &--right-leave-to
|
||||
opacity: 0
|
||||
transform: rotateX(90deg)
|
||||
z-index: ($z-notify - 1)
|
||||
|
||||
&--bottom-left-enter-from, &--bottom-left-leave-to,
|
||||
&--bottom-enter-from, &--bottom-leave-to,
|
||||
&--bottom-right-enter-from, &--bottom-right-leave-to
|
||||
opacity: 0
|
||||
transform: translateY(50px)
|
||||
z-index: ($z-notify - 1)
|
||||
|
||||
&--top-left-leave-active,
|
||||
&--top-leave-active,
|
||||
&--top-right-leave-active,
|
||||
&--left-leave-active,
|
||||
&--center-leave-active,
|
||||
&--right-leave-active,
|
||||
&--bottom-left-leave-active,
|
||||
&--bottom-leave-active,
|
||||
&--bottom-right-leave-active
|
||||
position: absolute
|
||||
z-index: ($z-notify - 1)
|
||||
margin-left: 0
|
||||
margin-right: 0
|
||||
|
||||
&--top-leave-active,
|
||||
&--center-leave-active
|
||||
top: 0
|
||||
|
||||
&--bottom-left-leave-active,
|
||||
&--bottom-leave-active,
|
||||
&--bottom-right-leave-active
|
||||
bottom: 0
|
||||
|
||||
@media (min-width: $breakpoint-sm-min)
|
||||
.q-notification
|
||||
max-width: 65vw
|
||||
|
||||
@keyframes q-notif-badge
|
||||
15%
|
||||
transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg)
|
||||
|
||||
30%
|
||||
transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)
|
||||
|
||||
45%
|
||||
transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)
|
||||
|
||||
60%
|
||||
transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)
|
||||
|
||||
75%
|
||||
transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)
|
||||
|
||||
@keyframes q-notif-progress
|
||||
0%
|
||||
transform: scaleX(1)
|
||||
100%
|
||||
transform: scaleX(0)
|
||||
420
Frontend-Learner/node_modules/quasar/src/plugins/platform/Platform.js
generated
vendored
Normal file
420
Frontend-Learner/node_modules/quasar/src/plugins/platform/Platform.js
generated
vendored
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
/* eslint-disable no-useless-escape */
|
||||
|
||||
import { ref, reactive } from 'vue'
|
||||
import { injectProp } from '../../utils/private.inject-obj-prop/inject-obj-prop.js'
|
||||
|
||||
/**
|
||||
* __ QUASAR_SSR __ -> runs on SSR on client or server
|
||||
* __ QUASAR_SSR_SERVER __ -> runs on SSR on server
|
||||
* __ QUASAR_SSR_CLIENT __ -> runs on SSR on client
|
||||
* __ QUASAR_SSR_PWA __ -> built with SSR+PWA; may run on SSR on client or on PWA client
|
||||
* (needs runtime detection)
|
||||
*/
|
||||
|
||||
export const isRuntimeSsrPreHydration = __QUASAR_SSR_SERVER__
|
||||
? { value: true }
|
||||
: ref(
|
||||
__QUASAR_SSR_CLIENT__ && (
|
||||
__QUASAR_SSR_PWA__ ? document.body.getAttribute('data-server-rendered') !== null : true
|
||||
)
|
||||
)
|
||||
|
||||
let preHydrationBrowser
|
||||
|
||||
function getMatch (userAgent, platformMatch) {
|
||||
const match = /(edg|edge|edga|edgios)\/([\w.]+)/.exec(userAgent)
|
||||
|| /(opr)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| /(vivaldi)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| /(chrome|crios)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| /(version)(applewebkit)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| /(webkit)[\/]([\w.]+).*(version)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| /(firefox|fxios)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| /(webkit)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| /(opera)(?:.*version|)[\/]([\w.]+)/.exec(userAgent)
|
||||
|| []
|
||||
|
||||
return {
|
||||
browser: match[ 5 ] || match[ 3 ] || match[ 1 ] || '',
|
||||
version: match[ 4 ] || match[ 2 ] || '0',
|
||||
platform: platformMatch[ 0 ] || ''
|
||||
}
|
||||
}
|
||||
|
||||
function getPlatformMatch (userAgent) {
|
||||
return /(ipad)/.exec(userAgent)
|
||||
|| /(ipod)/.exec(userAgent)
|
||||
|| /(windows phone)/.exec(userAgent)
|
||||
|| /(iphone)/.exec(userAgent)
|
||||
|| /(kindle)/.exec(userAgent)
|
||||
|| /(silk)/.exec(userAgent)
|
||||
|| /(android)/.exec(userAgent)
|
||||
|| /(win)/.exec(userAgent)
|
||||
|| /(mac)/.exec(userAgent)
|
||||
|| /(linux)/.exec(userAgent)
|
||||
|| /(cros)/.exec(userAgent)
|
||||
// TODO: Remove BlackBerry detection. BlackBerry OS, BlackBerry 10, and BlackBerry PlayBook OS
|
||||
// is officially dead as of January 4, 2022 (https://www.blackberry.com/us/en/support/devices/end-of-life)
|
||||
|| /(playbook)/.exec(userAgent)
|
||||
|| /(bb)/.exec(userAgent)
|
||||
|| /(blackberry)/.exec(userAgent)
|
||||
|| []
|
||||
}
|
||||
|
||||
const hasTouch = __QUASAR_SSR_SERVER__
|
||||
? false
|
||||
: 'ontouchstart' in window || window.navigator.maxTouchPoints > 0
|
||||
|
||||
function getPlatform (UA) {
|
||||
const userAgent = UA.toLowerCase()
|
||||
const platformMatch = getPlatformMatch(userAgent)
|
||||
const matched = getMatch(userAgent, platformMatch)
|
||||
const browser = {
|
||||
mobile: false,
|
||||
desktop: false,
|
||||
|
||||
cordova: false,
|
||||
capacitor: false,
|
||||
nativeMobile: false,
|
||||
// nativeMobileWrapper: void 0,
|
||||
electron: false,
|
||||
bex: false,
|
||||
|
||||
linux: false,
|
||||
mac: false,
|
||||
win: false,
|
||||
cros: false,
|
||||
|
||||
chrome: false,
|
||||
firefox: false,
|
||||
opera: false,
|
||||
safari: false,
|
||||
vivaldi: false,
|
||||
edge: false,
|
||||
edgeChromium: false,
|
||||
ie: false,
|
||||
webkit: false,
|
||||
|
||||
android: false,
|
||||
ios: false,
|
||||
ipad: false,
|
||||
iphone: false,
|
||||
ipod: false,
|
||||
kindle: false,
|
||||
winphone: false,
|
||||
blackberry: false,
|
||||
playbook: false,
|
||||
silk: false
|
||||
}
|
||||
|
||||
if (matched.browser) {
|
||||
browser[ matched.browser ] = true
|
||||
browser.version = matched.version
|
||||
browser.versionNumber = parseInt(matched.version, 10)
|
||||
}
|
||||
|
||||
if (matched.platform) {
|
||||
browser[ matched.platform ] = true
|
||||
}
|
||||
|
||||
const knownMobiles = browser.android
|
||||
|| browser.ios
|
||||
|| browser.bb
|
||||
|| browser.blackberry
|
||||
|| browser.ipad
|
||||
|| browser.iphone
|
||||
|| browser.ipod
|
||||
|| browser.kindle
|
||||
|| browser.playbook
|
||||
|| browser.silk
|
||||
|| browser[ 'windows phone' ]
|
||||
|
||||
// These are all considered mobile platforms, meaning they run a mobile browser
|
||||
if (
|
||||
knownMobiles === true
|
||||
|| userAgent.indexOf('mobile') !== -1
|
||||
) {
|
||||
browser.mobile = true
|
||||
}
|
||||
// If it's not mobile we should consider it's desktop platform, meaning it runs a desktop browser
|
||||
// It's a workaround for anonymized user agents
|
||||
// (browser.cros || browser.mac || browser.linux || browser.win)
|
||||
else {
|
||||
browser.desktop = true
|
||||
}
|
||||
|
||||
if (browser[ 'windows phone' ]) {
|
||||
browser.winphone = true
|
||||
delete browser[ 'windows phone' ]
|
||||
}
|
||||
|
||||
if (browser.edga || browser.edgios || browser.edg) {
|
||||
browser.edge = true
|
||||
matched.browser = 'edge'
|
||||
}
|
||||
else if (browser.crios) {
|
||||
browser.chrome = true
|
||||
matched.browser = 'chrome'
|
||||
}
|
||||
else if (browser.fxios) {
|
||||
browser.firefox = true
|
||||
matched.browser = 'firefox'
|
||||
}
|
||||
|
||||
// Set iOS if on iPod, iPad or iPhone
|
||||
if (browser.ipod || browser.ipad || browser.iphone) {
|
||||
browser.ios = true
|
||||
}
|
||||
|
||||
if (browser.vivaldi) {
|
||||
matched.browser = 'vivaldi'
|
||||
browser.vivaldi = true
|
||||
}
|
||||
|
||||
// TODO: The assumption about WebKit based browsers below is not completely accurate.
|
||||
// Google released Blink(a fork of WebKit) engine on April 3, 2013, which is really different than WebKit today.
|
||||
// Today, one might want to check for WebKit to deal with its bugs, which is used on all browsers on iOS, and Safari browser on all platforms.
|
||||
if (
|
||||
// Chrome, Opera 15+, Vivaldi and Safari are webkit based browsers
|
||||
browser.chrome
|
||||
|| browser.opr
|
||||
|| browser.safari
|
||||
|| browser.vivaldi
|
||||
// we expect unknown, non iOS mobile browsers to be webkit based
|
||||
|| (
|
||||
browser.mobile === true
|
||||
&& browser.ios !== true
|
||||
&& knownMobiles !== true
|
||||
)
|
||||
) {
|
||||
browser.webkit = true
|
||||
}
|
||||
|
||||
// Opera 15+ are identified as opr
|
||||
if (browser.opr) {
|
||||
matched.browser = 'opera'
|
||||
browser.opera = true
|
||||
}
|
||||
|
||||
// Some browsers are marked as Safari but are not
|
||||
if (browser.safari) {
|
||||
if (browser.blackberry || browser.bb) {
|
||||
matched.browser = 'blackberry'
|
||||
browser.blackberry = true
|
||||
}
|
||||
else if (browser.playbook) {
|
||||
matched.browser = 'playbook'
|
||||
browser.playbook = true
|
||||
}
|
||||
else if (browser.android) {
|
||||
matched.browser = 'android'
|
||||
browser.android = true
|
||||
}
|
||||
else if (browser.kindle) {
|
||||
matched.browser = 'kindle'
|
||||
browser.kindle = true
|
||||
}
|
||||
else if (browser.silk) {
|
||||
matched.browser = 'silk'
|
||||
browser.silk = true
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the name and platform variable
|
||||
browser.name = matched.browser
|
||||
browser.platform = matched.platform
|
||||
|
||||
if (__QUASAR_SSR_SERVER__ !== true) {
|
||||
if (userAgent.indexOf('electron') !== -1) {
|
||||
browser.electron = true
|
||||
}
|
||||
else if (document.location.href.indexOf('-extension://') !== -1) {
|
||||
browser.bex = true
|
||||
}
|
||||
else {
|
||||
if (window.Capacitor !== void 0) {
|
||||
browser.capacitor = true
|
||||
browser.nativeMobile = true
|
||||
browser.nativeMobileWrapper = 'capacitor'
|
||||
}
|
||||
else if (window._cordovaNative !== void 0 || window.cordova !== void 0) {
|
||||
browser.cordova = true
|
||||
browser.nativeMobile = true
|
||||
browser.nativeMobileWrapper = 'cordova'
|
||||
}
|
||||
|
||||
if (isRuntimeSsrPreHydration.value === true) {
|
||||
/*
|
||||
* We need to remember the current state as
|
||||
* everything that follows can only be corrected client-side,
|
||||
* but we don't want to brake the hydration.
|
||||
*
|
||||
* The "client" object is imported throughout the UI and should
|
||||
* be as accurate as possible given all the knowledge that we posses
|
||||
* because decisions are required to be made immediately, even
|
||||
* before the hydration occurs.
|
||||
*/
|
||||
preHydrationBrowser = { is: { ...browser } }
|
||||
}
|
||||
|
||||
/*
|
||||
* All the following should be client-side corrections only
|
||||
*/
|
||||
|
||||
if (
|
||||
hasTouch === true
|
||||
&& browser.mac === true
|
||||
&& (
|
||||
(browser.desktop === true && browser.safari === true)
|
||||
|| (
|
||||
browser.nativeMobile === true
|
||||
&& browser.android !== true
|
||||
&& browser.ios !== true
|
||||
&& browser.ipad !== true
|
||||
)
|
||||
)
|
||||
) {
|
||||
/*
|
||||
* Correction needed for iOS since the default
|
||||
* setting on iPad is to request desktop view; if we have
|
||||
* touch support and the user agent says it's a
|
||||
* desktop, we infer that it's an iPhone/iPad with desktop view
|
||||
* so we must fix the false positives
|
||||
*/
|
||||
|
||||
delete browser.mac
|
||||
delete browser.desktop
|
||||
|
||||
const platform = Math.min(window.innerHeight, window.innerWidth) > 414
|
||||
? 'ipad'
|
||||
: 'iphone'
|
||||
|
||||
Object.assign(browser, {
|
||||
mobile: true,
|
||||
ios: true,
|
||||
platform,
|
||||
[ platform ]: true
|
||||
})
|
||||
}
|
||||
|
||||
if (
|
||||
browser.mobile !== true
|
||||
&& window.navigator.userAgentData
|
||||
&& window.navigator.userAgentData.mobile
|
||||
) {
|
||||
/*
|
||||
* Correction needed on client-side when
|
||||
* we also have the navigator userAgentData
|
||||
*/
|
||||
|
||||
delete browser.desktop
|
||||
browser.mobile = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return browser
|
||||
}
|
||||
|
||||
const userAgent = __QUASAR_SSR_SERVER__
|
||||
? ''
|
||||
: navigator.userAgent || navigator.vendor || window.opera
|
||||
|
||||
const ssrClient = {
|
||||
has: {
|
||||
touch: false,
|
||||
webStorage: false
|
||||
},
|
||||
within: { iframe: false }
|
||||
}
|
||||
|
||||
// We export "client" for hydration error-free parts,
|
||||
// like touch directives who do not (and must NOT) wait
|
||||
// for the client takeover;
|
||||
// Do NOT import this directly in your app, unless you really know
|
||||
// what you are doing.
|
||||
export const client = __QUASAR_SSR_SERVER__
|
||||
? ssrClient
|
||||
: {
|
||||
userAgent,
|
||||
is: getPlatform(userAgent),
|
||||
has: {
|
||||
touch: hasTouch
|
||||
},
|
||||
within: {
|
||||
iframe: window.self !== window.top
|
||||
}
|
||||
}
|
||||
|
||||
const Platform = {
|
||||
install (opts) {
|
||||
const { $q } = opts
|
||||
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
$q.platform = this.parseSSR(opts.ssrContext)
|
||||
}
|
||||
else if (isRuntimeSsrPreHydration.value === true) {
|
||||
// takeover should increase accuracy for
|
||||
// the rest of the props; we also avoid
|
||||
// hydration errors
|
||||
opts.onSSRHydrated.push(() => {
|
||||
Object.assign($q.platform, client)
|
||||
isRuntimeSsrPreHydration.value = false
|
||||
})
|
||||
|
||||
// we need to make platform reactive
|
||||
// for the takeover phase
|
||||
$q.platform = reactive(this)
|
||||
}
|
||||
else {
|
||||
$q.platform = this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
Platform.parseSSR = (ssrContext) => {
|
||||
const userAgent = ssrContext.req.headers[ 'user-agent' ] || ssrContext.req.headers[ 'User-Agent' ] || ''
|
||||
return {
|
||||
...client,
|
||||
userAgent,
|
||||
is: getPlatform(userAgent)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// do not access window.localStorage without
|
||||
// devland actually using it as this will get
|
||||
// reported under "Cookies" in Google Chrome
|
||||
let hasWebStorage
|
||||
|
||||
injectProp(client.has, 'webStorage', () => {
|
||||
if (hasWebStorage !== void 0) {
|
||||
return hasWebStorage
|
||||
}
|
||||
|
||||
try {
|
||||
if (window.localStorage) {
|
||||
hasWebStorage = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
catch (_) {}
|
||||
|
||||
hasWebStorage = false
|
||||
return false
|
||||
})
|
||||
|
||||
Object.assign(Platform, client)
|
||||
|
||||
if (isRuntimeSsrPreHydration.value === true) {
|
||||
// must match with server-side before
|
||||
// client taking over in order to prevent
|
||||
// hydration errors
|
||||
Object.assign(Platform, preHydrationBrowser, ssrClient)
|
||||
|
||||
// free up memory
|
||||
preHydrationBrowser = null
|
||||
}
|
||||
}
|
||||
|
||||
export default Platform
|
||||
221
Frontend-Learner/node_modules/quasar/src/plugins/platform/Platform.json
generated
vendored
Normal file
221
Frontend-Learner/node_modules/quasar/src/plugins/platform/Platform.json
generated
vendored
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/options/platform-detection"
|
||||
},
|
||||
|
||||
"injection": "$q.platform",
|
||||
|
||||
"props": {
|
||||
"userAgent": {
|
||||
"type": "String",
|
||||
"desc": "Client browser User Agent",
|
||||
"examples": [ "'mozilla/5.0 (macintosh; intel mac os x 10_14_5) applewebkit/537.36 (khtml, like gecko) chrome/75.0.3770.100 safari/537.36'" ]
|
||||
},
|
||||
|
||||
"is": {
|
||||
"type": "Object",
|
||||
"desc": "Client browser details (property names depend on browser)",
|
||||
"definition": {
|
||||
"name": {
|
||||
"type": "String",
|
||||
"desc": "Browser name",
|
||||
"examples": [ "'chrome'" ]
|
||||
},
|
||||
"platform": {
|
||||
"type": "String",
|
||||
"desc": "Platform name",
|
||||
"examples": [ "'mac'" ]
|
||||
},
|
||||
"version": {
|
||||
"type": "String",
|
||||
"required": false,
|
||||
"desc": "Detailed browser version",
|
||||
"examples": [ "'71.0.3578.98'" ]
|
||||
},
|
||||
"versionNumber": {
|
||||
"type": "Number",
|
||||
"required": false,
|
||||
"desc": "Major browser version as a number"
|
||||
},
|
||||
|
||||
"mobile": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the platform is mobile"
|
||||
},
|
||||
"desktop": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the platform is desktop"
|
||||
},
|
||||
|
||||
"cordova": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the platform is Cordova"
|
||||
},
|
||||
"capacitor": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the platform is Capacitor"
|
||||
},
|
||||
"nativeMobile": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the platform is a native mobile wrapper"
|
||||
},
|
||||
"nativeMobileWrapper": {
|
||||
"type": "String",
|
||||
"required": false,
|
||||
"values": [ "'cordova'", "'capacitor'" ],
|
||||
"desc": "Type of the native mobile wrapper"
|
||||
},
|
||||
"electron": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the platform is Electron"
|
||||
},
|
||||
"bex": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the platform is BEX(Browser Extension)"
|
||||
},
|
||||
|
||||
"linux": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the operating system is Linux"
|
||||
},
|
||||
"mac": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the operating system is Mac OS"
|
||||
},
|
||||
"win": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the operating system is Windows"
|
||||
},
|
||||
"cros": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the operating system is Chrome OS"
|
||||
},
|
||||
|
||||
"chrome": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Google Chrome"
|
||||
},
|
||||
"firefox": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Firefox"
|
||||
},
|
||||
"opera": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Opera"
|
||||
},
|
||||
"safari": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Safari"
|
||||
},
|
||||
"vivaldi": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Vivaldi"
|
||||
},
|
||||
"edge": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Microsoft Edge Legacy"
|
||||
},
|
||||
"edgeChromium": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Microsoft Edge (Chromium)"
|
||||
},
|
||||
"ie": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Internet Explorer"
|
||||
},
|
||||
"webkit": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is a Webkit or Webkit-based one"
|
||||
},
|
||||
|
||||
"android": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the operating system is Android"
|
||||
},
|
||||
"ios": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the operating system is iOS"
|
||||
},
|
||||
"ipad": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the device is an iPad"
|
||||
},
|
||||
"iphone": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the device is an iPhone"
|
||||
},
|
||||
"ipod": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the device is an iPod"
|
||||
},
|
||||
"kindle": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the device is a Kindle"
|
||||
},
|
||||
"winphone": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the operating system is Windows Phone"
|
||||
},
|
||||
"blackberry": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the device is a Blackberry"
|
||||
},
|
||||
"playbook": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the device is a Blackberry Playbook"
|
||||
},
|
||||
"silk": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether the browser is Amazon Silk"
|
||||
}
|
||||
},
|
||||
"examples": [ "{ chrome: true, version: '71.0.3578.98', versionNumber: 71, mac: true, desktop: true, webkit: true, name: 'chrome', platform: 'mac' }" ]
|
||||
},
|
||||
|
||||
"has": {
|
||||
"type": "Object",
|
||||
"desc": "Client browser detectable properties",
|
||||
"definition": {
|
||||
"touch": {
|
||||
"type": "Boolean",
|
||||
"desc": "Client browser runs on device with touch support"
|
||||
},
|
||||
"webStorage": {
|
||||
"type": "Boolean",
|
||||
"desc": "Client browser has Web Storage support"
|
||||
}
|
||||
},
|
||||
"examples": [ "{ touch: false, webStorage: true }" ]
|
||||
},
|
||||
|
||||
"within": {
|
||||
"type": "Object",
|
||||
"desc": "Client browser environment",
|
||||
"definition": {
|
||||
"iframe": {
|
||||
"type": "Boolean",
|
||||
"desc": "Does the app run under an iframe?"
|
||||
}
|
||||
},
|
||||
"examples": [ "{ iframe: false }" ]
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"parseSSR": {
|
||||
"desc": "For SSR usage only, and only on the global import (not on $q.platform)",
|
||||
"params": {
|
||||
"ssrContext": {
|
||||
"type": "Object",
|
||||
"desc": "SSR Context Object",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Object",
|
||||
"tsType": "Platform",
|
||||
"desc": "Platform object (like $q.platform) for SSR usage purposes"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
112
Frontend-Learner/node_modules/quasar/src/plugins/platform/Platform.test.js
generated
vendored
Normal file
112
Frontend-Learner/node_modules/quasar/src/plugins/platform/Platform.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* Ignored specs:
|
||||
* [(method)parseSSR]
|
||||
*/
|
||||
|
||||
import { describe, test, expect } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import Platform from './Platform.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
describe('[Platform API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
expect(Platform).toBe(wrapper.vm.$q.platform)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)userAgent]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Platform.userAgent).toBeTypeOf('string')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)is]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
|
||||
const expected = {
|
||||
name: expect.any(String),
|
||||
platform: expect.any(String),
|
||||
version: expect.any(String),
|
||||
versionNumber: expect.any(Number),
|
||||
|
||||
mobile: expect.any(Boolean),
|
||||
desktop: expect.any(Boolean),
|
||||
|
||||
cordova: expect.any(Boolean),
|
||||
capacitor: expect.any(Boolean),
|
||||
nativeMobile: expect.any(Boolean),
|
||||
nativeMobileWrapper: expect.$any([
|
||||
'cordova',
|
||||
'capacitor'
|
||||
]),
|
||||
electron: expect.any(Boolean),
|
||||
bex: expect.any(Boolean),
|
||||
|
||||
linux: expect.any(Boolean),
|
||||
mac: expect.any(Boolean),
|
||||
win: expect.any(Boolean),
|
||||
cros: expect.any(Boolean),
|
||||
|
||||
chrome: expect.any(Boolean),
|
||||
firefox: expect.any(Boolean),
|
||||
opera: expect.any(Boolean),
|
||||
safari: expect.any(Boolean),
|
||||
vivaldi: expect.any(Boolean),
|
||||
edge: expect.any(Boolean),
|
||||
edgeChromium: expect.any(Boolean),
|
||||
ie: expect.any(Boolean),
|
||||
webkit: expect.any(Boolean),
|
||||
|
||||
android: expect.any(Boolean),
|
||||
ios: expect.any(Boolean),
|
||||
ipad: expect.any(Boolean),
|
||||
iphone: expect.any(Boolean),
|
||||
ipod: expect.any(Boolean),
|
||||
kindle: expect.any(Boolean),
|
||||
winphone: expect.any(Boolean),
|
||||
blackberry: expect.any(Boolean),
|
||||
playbook: expect.any(Boolean),
|
||||
silk: expect.any(Boolean)
|
||||
}
|
||||
|
||||
const actualKeys = Object.keys(Platform.is)
|
||||
|
||||
expect(actualKeys).not.toHaveLength(0)
|
||||
|
||||
expect(actualKeys).toSatisfy(
|
||||
keys => keys.every(key => expected[ key ] !== void 0)
|
||||
)
|
||||
|
||||
actualKeys.forEach(key => {
|
||||
expect(Platform.is[ key ]).toStrictEqual(expected[ key ])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)has]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Platform.has).toStrictEqual({
|
||||
touch: expect.any(Boolean),
|
||||
webStorage: expect.any(Boolean)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)within]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Platform.within).toStrictEqual({
|
||||
iframe: expect.any(Boolean)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
142
Frontend-Learner/node_modules/quasar/src/plugins/private.body/Body.js
generated
vendored
Normal file
142
Frontend-Learner/node_modules/quasar/src/plugins/private.body/Body.js
generated
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import setCssVar from '../../utils/css-var/set-css-var.js'
|
||||
import { noop } from '../../utils/event/event.js'
|
||||
import { onKeyDownComposition } from '../../utils/private.keyboard/key-composition.js'
|
||||
|
||||
import { isRuntimeSsrPreHydration, client } from '../platform/Platform.js'
|
||||
|
||||
function getMobilePlatform (is) {
|
||||
if (is.ios === true) return 'ios'
|
||||
if (is.android === true) return 'android'
|
||||
}
|
||||
|
||||
function getBodyClasses ({ is, has, within }, cfg) {
|
||||
const cls = [
|
||||
is.desktop === true ? 'desktop' : 'mobile',
|
||||
`${ has.touch === false ? 'no-' : '' }touch`
|
||||
]
|
||||
|
||||
if (is.mobile === true) {
|
||||
const mobile = getMobilePlatform(is)
|
||||
mobile !== void 0 && cls.push('platform-' + mobile)
|
||||
}
|
||||
|
||||
if (is.nativeMobile === true) {
|
||||
const type = is.nativeMobileWrapper
|
||||
|
||||
cls.push(type)
|
||||
cls.push('native-mobile')
|
||||
|
||||
if (
|
||||
is.ios === true
|
||||
&& (cfg[ type ] === void 0 || cfg[ type ].iosStatusBarPadding !== false)
|
||||
) {
|
||||
cls.push('q-ios-padding')
|
||||
}
|
||||
}
|
||||
else if (is.electron === true) {
|
||||
cls.push('electron')
|
||||
}
|
||||
else if (is.bex === true) {
|
||||
cls.push('bex')
|
||||
}
|
||||
|
||||
within.iframe === true && cls.push('within-iframe')
|
||||
|
||||
return cls
|
||||
}
|
||||
|
||||
function applyClientSsrCorrections () {
|
||||
const { is } = client
|
||||
const classes = document.body.className
|
||||
|
||||
const classList = new Set(classes.replace(/ {2}/g, ' ').split(' '))
|
||||
|
||||
if (is.nativeMobile !== true && is.electron !== true && is.bex !== true) {
|
||||
if (is.desktop === true) {
|
||||
classList.delete('mobile')
|
||||
classList.delete('platform-ios')
|
||||
classList.delete('platform-android')
|
||||
classList.add('desktop')
|
||||
}
|
||||
else if (is.mobile === true) {
|
||||
classList.delete('desktop')
|
||||
classList.add('mobile')
|
||||
|
||||
classList.delete('platform-ios')
|
||||
classList.delete('platform-android')
|
||||
|
||||
const mobile = getMobilePlatform(is)
|
||||
if (mobile !== void 0) {
|
||||
classList.add(`platform-${ mobile }`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (client.has.touch === true) {
|
||||
classList.delete('no-touch')
|
||||
classList.add('touch')
|
||||
}
|
||||
|
||||
if (client.within.iframe === true) {
|
||||
classList.add('within-iframe')
|
||||
}
|
||||
|
||||
const newCls = Array.from(classList).join(' ')
|
||||
|
||||
if (classes !== newCls) {
|
||||
document.body.className = newCls
|
||||
}
|
||||
}
|
||||
|
||||
function setColors (brand) {
|
||||
for (const color in brand) {
|
||||
setCssVar(color, brand[ color ])
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
install (opts) {
|
||||
if (__QUASAR_SSR_SERVER__) {
|
||||
const { $q, ssrContext } = opts
|
||||
const cls = getBodyClasses($q.platform, $q.config)
|
||||
|
||||
if ($q.config.screen?.bodyClass === true) {
|
||||
cls.push('screen--xs')
|
||||
}
|
||||
|
||||
ssrContext._meta.bodyClasses += cls.join(' ')
|
||||
|
||||
const brand = $q.config.brand
|
||||
if (brand !== void 0) {
|
||||
const vars = Object.keys(brand)
|
||||
.map(key => `--q-${ key }:${ brand[ key ] };`)
|
||||
.join('')
|
||||
|
||||
ssrContext._meta.endingHeadTags += `<style>:root{${ vars }}</style>`
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (this.__installed === true) return
|
||||
|
||||
if (isRuntimeSsrPreHydration.value === true) {
|
||||
applyClientSsrCorrections()
|
||||
}
|
||||
else {
|
||||
const { $q } = opts
|
||||
|
||||
$q.config.brand !== void 0 && setColors($q.config.brand)
|
||||
|
||||
const cls = getBodyClasses(client, $q.config)
|
||||
document.body.classList.add.apply(document.body.classList, cls)
|
||||
}
|
||||
|
||||
if (client.is.ios === true) {
|
||||
// needed for iOS button active state
|
||||
document.body.addEventListener('touchstart', noop)
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', onKeyDownComposition, true)
|
||||
}
|
||||
}
|
||||
28
Frontend-Learner/node_modules/quasar/src/plugins/private.body/Body.test.js
generated
vendored
Normal file
28
Frontend-Learner/node_modules/quasar/src/plugins/private.body/Body.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import Body from './Body.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
describe('[Body API]', () => {
|
||||
describe('[Functions]', () => {
|
||||
describe('[(function)install]', () => {
|
||||
test('should be defined correctly', () => {
|
||||
expect(Body).toBeTypeOf('object')
|
||||
|
||||
expect(
|
||||
Body.install
|
||||
).toBeTypeOf('function')
|
||||
})
|
||||
|
||||
test('sets body classes', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(
|
||||
document.body.getAttribute('class')
|
||||
).toBe('desktop touch body--light')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
112
Frontend-Learner/node_modules/quasar/src/plugins/private.history/History.js
generated
vendored
Normal file
112
Frontend-Learner/node_modules/quasar/src/plugins/private.history/History.js
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
import { client } from '../platform/Platform.js'
|
||||
import { noop } from '../../utils/event/event.js'
|
||||
|
||||
const getTrue = () => true
|
||||
|
||||
function filterInvalidPath (path) {
|
||||
return typeof path === 'string'
|
||||
&& path !== ''
|
||||
&& path !== '/'
|
||||
&& path !== '#/'
|
||||
}
|
||||
|
||||
function normalizeExitPath (path) {
|
||||
path.startsWith('#') === true && (path = path.substring(1))
|
||||
path.startsWith('/') === false && (path = '/' + path)
|
||||
path.endsWith('/') === true && (path = path.substring(0, path.length - 1))
|
||||
return '#' + path
|
||||
}
|
||||
|
||||
function getShouldExitFn (cfg) {
|
||||
if (cfg.backButtonExit === false) {
|
||||
return () => false
|
||||
}
|
||||
|
||||
if (cfg.backButtonExit === '*') {
|
||||
return getTrue
|
||||
}
|
||||
|
||||
// Add default root path
|
||||
const exitPaths = [ '#/' ]
|
||||
|
||||
// Add custom exit paths
|
||||
Array.isArray(cfg.backButtonExit) === true && exitPaths.push(
|
||||
...cfg.backButtonExit.filter(filterInvalidPath).map(normalizeExitPath)
|
||||
)
|
||||
|
||||
return () => exitPaths.includes(window.location.hash)
|
||||
}
|
||||
|
||||
export default {
|
||||
__history: [],
|
||||
add: noop,
|
||||
remove: noop,
|
||||
|
||||
install ({ $q }) {
|
||||
if (__QUASAR_SSR_SERVER__ || this.__installed === true) return
|
||||
|
||||
const { cordova, capacitor } = client.is
|
||||
|
||||
if (cordova !== true && capacitor !== true) return
|
||||
|
||||
const qConf = $q.config[ cordova === true ? 'cordova' : 'capacitor' ]
|
||||
|
||||
if (qConf?.backButton === false) return
|
||||
|
||||
// if the '@capacitor/app' plugin is not installed
|
||||
// then we got nothing to do
|
||||
if (
|
||||
// if we're on Capacitor mode
|
||||
capacitor === true
|
||||
// and it's also not in Capacitor's main instance
|
||||
&& (window.Capacitor === void 0 || window.Capacitor.Plugins.App === void 0)
|
||||
) return
|
||||
|
||||
this.add = entry => {
|
||||
if (entry.condition === void 0) {
|
||||
entry.condition = getTrue
|
||||
}
|
||||
this.__history.push(entry)
|
||||
}
|
||||
|
||||
this.remove = entry => {
|
||||
const index = this.__history.indexOf(entry)
|
||||
if (index >= 0) {
|
||||
this.__history.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const shouldExit = getShouldExitFn(
|
||||
Object.assign(
|
||||
{ backButtonExit: true },
|
||||
qConf
|
||||
)
|
||||
)
|
||||
|
||||
const backHandler = () => {
|
||||
if (this.__history.length) {
|
||||
const entry = this.__history[ this.__history.length - 1 ]
|
||||
|
||||
if (entry.condition() === true) {
|
||||
this.__history.pop()
|
||||
entry.handler()
|
||||
}
|
||||
}
|
||||
else if (shouldExit() === true) {
|
||||
navigator.app.exitApp()
|
||||
}
|
||||
else {
|
||||
window.history.back()
|
||||
}
|
||||
}
|
||||
|
||||
if (cordova === true) {
|
||||
document.addEventListener('deviceready', () => {
|
||||
document.addEventListener('backbutton', backHandler, false)
|
||||
})
|
||||
}
|
||||
else {
|
||||
window.Capacitor.Plugins.App.addListener('backButton', backHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Frontend-Learner/node_modules/quasar/src/plugins/private.history/History.test.js
generated
vendored
Normal file
38
Frontend-Learner/node_modules/quasar/src/plugins/private.history/History.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import History from './History.js'
|
||||
|
||||
/**
|
||||
* Can't really fully test it since it handles
|
||||
* Capacitor and Cordova platforms
|
||||
*/
|
||||
|
||||
describe('[History API]', () => {
|
||||
describe('[Variables]', () => {
|
||||
describe('[(variable)__history]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(Array.isArray(History.__history)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(variable)add]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(History.add).toBeTypeOf('function')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(variable)remove]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(History.remove).toBeTypeOf('function')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Functions]', () => {
|
||||
describe('[(function)install]', () => {
|
||||
test('is defined correctly', () => {
|
||||
expect(History.install).toBeTypeOf('function')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
183
Frontend-Learner/node_modules/quasar/src/plugins/screen/Screen.js
generated
vendored
Normal file
183
Frontend-Learner/node_modules/quasar/src/plugins/screen/Screen.js
generated
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
import { isRuntimeSsrPreHydration, client } from '../platform/Platform.js'
|
||||
|
||||
import { createReactivePlugin } from '../../utils/private.create/create.js'
|
||||
import { listenOpts, noop } from '../../utils/event/event.js'
|
||||
import debounce from '../../utils/debounce/debounce.js'
|
||||
|
||||
const SIZE_LIST = [ 'sm', 'md', 'lg', 'xl' ]
|
||||
const { passive } = listenOpts
|
||||
|
||||
export default createReactivePlugin({
|
||||
width: 0,
|
||||
height: 0,
|
||||
name: 'xs',
|
||||
|
||||
sizes: {
|
||||
sm: 600,
|
||||
md: 1024,
|
||||
lg: 1440,
|
||||
xl: 1920
|
||||
},
|
||||
|
||||
lt: {
|
||||
sm: true,
|
||||
md: true,
|
||||
lg: true,
|
||||
xl: true
|
||||
},
|
||||
gt: {
|
||||
xs: false,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false
|
||||
},
|
||||
|
||||
xs: true,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: false
|
||||
}, {
|
||||
setSizes: noop,
|
||||
setDebounce: noop,
|
||||
|
||||
install ({ $q, onSSRHydrated }) {
|
||||
$q.screen = this
|
||||
|
||||
if (__QUASAR_SSR_SERVER__) return
|
||||
|
||||
if (this.__installed === true) {
|
||||
if ($q.config.screen !== void 0) {
|
||||
if ($q.config.screen.bodyClasses === false) {
|
||||
document.body.classList.remove(`screen--${ this.name }`)
|
||||
}
|
||||
else {
|
||||
this.__update(true)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const { visualViewport } = window
|
||||
const target = visualViewport || window
|
||||
const scrollingElement = document.scrollingElement || document.documentElement
|
||||
const getSize = visualViewport === void 0 || client.is.mobile === true
|
||||
? () => [
|
||||
Math.max(window.innerWidth, scrollingElement.clientWidth),
|
||||
Math.max(window.innerHeight, scrollingElement.clientHeight)
|
||||
]
|
||||
: () => [
|
||||
visualViewport.width * visualViewport.scale + window.innerWidth - scrollingElement.clientWidth,
|
||||
visualViewport.height * visualViewport.scale + window.innerHeight - scrollingElement.clientHeight
|
||||
]
|
||||
|
||||
const classes = $q.config.screen?.bodyClasses === true
|
||||
|
||||
this.__update = force => {
|
||||
const [ w, h ] = getSize()
|
||||
|
||||
if (h !== this.height) {
|
||||
this.height = h
|
||||
}
|
||||
|
||||
if (w !== this.width) {
|
||||
this.width = w
|
||||
}
|
||||
else if (force !== true) {
|
||||
return
|
||||
}
|
||||
|
||||
let s = this.sizes
|
||||
|
||||
this.gt.xs = w >= s.sm
|
||||
this.gt.sm = w >= s.md
|
||||
this.gt.md = w >= s.lg
|
||||
this.gt.lg = w >= s.xl
|
||||
this.lt.sm = w < s.sm
|
||||
this.lt.md = w < s.md
|
||||
this.lt.lg = w < s.lg
|
||||
this.lt.xl = w < s.xl
|
||||
this.xs = this.lt.sm
|
||||
this.sm = this.gt.xs === true && this.lt.md === true
|
||||
this.md = this.gt.sm === true && this.lt.lg === true
|
||||
this.lg = this.gt.md === true && this.lt.xl === true
|
||||
this.xl = this.gt.lg
|
||||
|
||||
s = (this.xs === true && 'xs')
|
||||
|| (this.sm === true && 'sm')
|
||||
|| (this.md === true && 'md')
|
||||
|| (this.lg === true && 'lg')
|
||||
|| 'xl'
|
||||
|
||||
if (s !== this.name) {
|
||||
if (classes === true) {
|
||||
document.body.classList.remove(`screen--${ this.name }`)
|
||||
document.body.classList.add(`screen--${ s }`)
|
||||
}
|
||||
this.name = s
|
||||
}
|
||||
}
|
||||
|
||||
let updateEvt, updateSizes = {}, updateDebounce = 16
|
||||
|
||||
this.setSizes = sizes => {
|
||||
SIZE_LIST.forEach(name => {
|
||||
if (sizes[ name ] !== void 0) {
|
||||
updateSizes[ name ] = sizes[ name ]
|
||||
}
|
||||
})
|
||||
}
|
||||
this.setDebounce = deb => {
|
||||
updateDebounce = deb
|
||||
}
|
||||
|
||||
const start = () => {
|
||||
const style = getComputedStyle(document.body)
|
||||
|
||||
// if css props available
|
||||
if (style.getPropertyValue('--q-size-sm')) {
|
||||
SIZE_LIST.forEach(name => {
|
||||
this.sizes[ name ] = parseInt(style.getPropertyValue(`--q-size-${ name }`), 10)
|
||||
})
|
||||
}
|
||||
|
||||
this.setSizes = sizes => {
|
||||
SIZE_LIST.forEach(name => {
|
||||
if (sizes[ name ]) {
|
||||
this.sizes[ name ] = sizes[ name ]
|
||||
}
|
||||
})
|
||||
this.__update(true)
|
||||
}
|
||||
|
||||
this.setDebounce = delay => {
|
||||
updateEvt !== void 0 && target.removeEventListener('resize', updateEvt, passive)
|
||||
updateEvt = delay > 0
|
||||
? debounce(this.__update, delay)
|
||||
: this.__update
|
||||
target.addEventListener('resize', updateEvt, passive)
|
||||
}
|
||||
|
||||
this.setDebounce(updateDebounce)
|
||||
|
||||
if (Object.keys(updateSizes).length !== 0) {
|
||||
this.setSizes(updateSizes)
|
||||
updateSizes = void 0 // free up memory
|
||||
}
|
||||
else {
|
||||
this.__update()
|
||||
}
|
||||
|
||||
// due to optimizations, this would be left out otherwise
|
||||
classes === true && this.name === 'xs'
|
||||
&& document.body.classList.add('screen--xs')
|
||||
}
|
||||
|
||||
if (isRuntimeSsrPreHydration.value === true) {
|
||||
onSSRHydrated.push(start)
|
||||
}
|
||||
else {
|
||||
start()
|
||||
}
|
||||
}
|
||||
})
|
||||
190
Frontend-Learner/node_modules/quasar/src/plugins/screen/Screen.json
generated
vendored
Normal file
190
Frontend-Learner/node_modules/quasar/src/plugins/screen/Screen.json
generated
vendored
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/options/screen-plugin"
|
||||
},
|
||||
|
||||
"injection": "$q.screen",
|
||||
|
||||
"quasarConfOptions": {
|
||||
"propName": "screen",
|
||||
"type": "Object",
|
||||
"definition": {
|
||||
"bodyClasses": {
|
||||
"type": "Boolean",
|
||||
"desc": "Whether to apply CSS classes for the current window breakpoint to the body element"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"props": {
|
||||
"width": {
|
||||
"type": "Number",
|
||||
"desc": "Screen width (in pixels)",
|
||||
"reactive": true,
|
||||
"examples": [ "452" ]
|
||||
},
|
||||
|
||||
"height": {
|
||||
"type": "Number",
|
||||
"desc": "Screen height (in pixels)",
|
||||
"reactive": true,
|
||||
"examples": [ "721" ]
|
||||
},
|
||||
|
||||
"name": {
|
||||
"type": "String",
|
||||
"desc": "Tells current window breakpoint",
|
||||
"values": [ "'xs'", "'sm'", "'md'", "'lg'", "'xl'" ],
|
||||
"reactive": true
|
||||
},
|
||||
|
||||
"sizes": {
|
||||
"type": "Object",
|
||||
"desc": "Breakpoints (in pixels)",
|
||||
"definition": {
|
||||
"sm": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
},
|
||||
"md": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
},
|
||||
"lg": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
},
|
||||
"xl": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
}
|
||||
},
|
||||
"reactive": true,
|
||||
"examples": [ "{ sm: 600, md: 1024, lg: 1440, xl: 1920 }" ]
|
||||
},
|
||||
|
||||
"lt": {
|
||||
"type": "Object",
|
||||
"desc": "Tells if current screen width is lower than breakpoint-name",
|
||||
"reactive": true,
|
||||
"definition": {
|
||||
"sm": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width lower than this breakpoint's lowest limit?"
|
||||
},
|
||||
"md": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width lower than this breakpoint's lowest limit?"
|
||||
},
|
||||
"lg": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width lower than this breakpoint's lowest limit?"
|
||||
},
|
||||
"xl": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width lower than this breakpoint's lowest limit?"
|
||||
}
|
||||
},
|
||||
"examples": [ "{ sm: false, md: true, lg: true, xl: true }" ]
|
||||
},
|
||||
|
||||
"gt": {
|
||||
"type": "Object",
|
||||
"desc": "Tells if current screen width is greater than breakpoint-name",
|
||||
"reactive": true,
|
||||
"definition": {
|
||||
"xs": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width greater than this breakpoint's max limit?"
|
||||
},
|
||||
"sm": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width greater than this breakpoint's max limit?"
|
||||
},
|
||||
"md": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width greater than this breakpoint's max limit?"
|
||||
},
|
||||
"lg": {
|
||||
"type": "Boolean",
|
||||
"desc": "Is current screen width greater than this breakpoint's max limit?"
|
||||
}
|
||||
},
|
||||
"examples": [ "{ xs: true, sm: true, md: false, lg: false, xl: false }" ]
|
||||
},
|
||||
|
||||
"xs": {
|
||||
"type": "Boolean",
|
||||
"desc": "Current screen width fits exactly 'xs' breakpoint",
|
||||
"reactive": true
|
||||
},
|
||||
|
||||
"sm": {
|
||||
"type": "Boolean",
|
||||
"desc": "Current screen width fits exactly 'sm' breakpoint",
|
||||
"reactive": true
|
||||
},
|
||||
|
||||
"md": {
|
||||
"type": "Boolean",
|
||||
"desc": "Current screen width fits exactly 'md' breakpoint",
|
||||
"reactive": true
|
||||
},
|
||||
|
||||
"lg": {
|
||||
"type": "Boolean",
|
||||
"desc": "Current screen width fits exactly 'lg' breakpoint",
|
||||
"reactive": true
|
||||
},
|
||||
|
||||
"xl": {
|
||||
"type": "Boolean",
|
||||
"desc": "Current screen width fits exactly 'xl' breakpoint",
|
||||
"reactive": true
|
||||
}
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"setSizes": {
|
||||
"desc": "Override default breakpoint sizes",
|
||||
"params": {
|
||||
"breakpoints": {
|
||||
"type": "Object",
|
||||
"desc": "Pick what you want to override",
|
||||
"definition": {
|
||||
"sm": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
},
|
||||
"md": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
},
|
||||
"lg": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
},
|
||||
"xl": {
|
||||
"type": "Number",
|
||||
"desc": "Breakpoint width size (minimum size)"
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"setDebounce": {
|
||||
"desc": "Debounce update of all props when screen width/height changes",
|
||||
"params": {
|
||||
"amount": {
|
||||
"type": "Number",
|
||||
"desc": "Amount in milliseconds",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
}
|
||||
}
|
||||
}
|
||||
453
Frontend-Learner/node_modules/quasar/src/plugins/screen/Screen.test.js
generated
vendored
Normal file
453
Frontend-Learner/node_modules/quasar/src/plugins/screen/Screen.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import Screen from './Screen.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllTimers()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
function setWidth (width) {
|
||||
window.innerWidth = width
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
vi.runAllTimers()
|
||||
}
|
||||
|
||||
function setHeight (height) {
|
||||
window.innerHeight = height
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
vi.runAllTimers()
|
||||
}
|
||||
|
||||
describe('[Screen API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const wrapper = mountPlugin()
|
||||
expect(Screen).toBe(wrapper.vm.$q.screen)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Props]', () => {
|
||||
describe('[(prop)width]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.width).toBeTypeOf('number')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.width).not.toBe(100)
|
||||
setWidth(100)
|
||||
vi.runAllTimers()
|
||||
expect(Screen.width).toBe(100)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)height]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.height).toBeTypeOf('number')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.height).not.toBe(100)
|
||||
setHeight(100)
|
||||
expect(Screen.height).toBe(100)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)name]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect([ 'xs', 'sm', 'md', 'lg', 'xl' ]).toContain(Screen.name)
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(500)
|
||||
expect(Screen.name).toBe('xs')
|
||||
|
||||
setWidth(800)
|
||||
expect(Screen.name).toBe('sm')
|
||||
|
||||
setWidth(1200)
|
||||
expect(Screen.name).toBe('md')
|
||||
|
||||
setWidth(1600)
|
||||
expect(Screen.name).toBe('lg')
|
||||
|
||||
setWidth(2000)
|
||||
expect(Screen.name).toBe('xl')
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)sizes]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.sizes).toStrictEqual({
|
||||
sm: expect.any(Number),
|
||||
md: expect.any(Number),
|
||||
lg: expect.any(Number),
|
||||
xl: expect.any(Number)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)lt]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.lt).toStrictEqual({
|
||||
sm: expect.any(Boolean),
|
||||
md: expect.any(Boolean),
|
||||
lg: expect.any(Boolean),
|
||||
xl: expect.any(Boolean)
|
||||
})
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(500) // xs
|
||||
expect(Screen.lt).toStrictEqual({
|
||||
sm: true,
|
||||
md: true,
|
||||
lg: true,
|
||||
xl: true
|
||||
})
|
||||
|
||||
setWidth(800) // sm
|
||||
expect(Screen.lt).toStrictEqual({
|
||||
sm: false,
|
||||
md: true,
|
||||
lg: true,
|
||||
xl: true
|
||||
})
|
||||
|
||||
setWidth(1200) // md
|
||||
expect(Screen.lt).toStrictEqual({
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: true,
|
||||
xl: true
|
||||
})
|
||||
|
||||
setWidth(1600) // lg
|
||||
expect(Screen.lt).toStrictEqual({
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: true
|
||||
})
|
||||
|
||||
setWidth(2000) // xl
|
||||
expect(Screen.lt).toStrictEqual({
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: false
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)gt]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.gt).toStrictEqual({
|
||||
xs: expect.any(Boolean),
|
||||
sm: expect.any(Boolean),
|
||||
md: expect.any(Boolean),
|
||||
lg: expect.any(Boolean)
|
||||
})
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(500) // xs
|
||||
expect(Screen.gt).toStrictEqual({
|
||||
xs: false,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false
|
||||
})
|
||||
|
||||
setWidth(800) // sm
|
||||
expect(Screen.gt).toStrictEqual({
|
||||
xs: true,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false
|
||||
})
|
||||
|
||||
setWidth(1200) // md
|
||||
expect(Screen.gt).toStrictEqual({
|
||||
xs: true,
|
||||
sm: true,
|
||||
md: false,
|
||||
lg: false
|
||||
})
|
||||
|
||||
setWidth(1600) // lg
|
||||
expect(Screen.gt).toStrictEqual({
|
||||
xs: true,
|
||||
sm: true,
|
||||
md: true,
|
||||
lg: false
|
||||
})
|
||||
|
||||
setWidth(2000) // xl
|
||||
expect(Screen.gt).toStrictEqual({
|
||||
xs: true,
|
||||
sm: true,
|
||||
md: true,
|
||||
lg: true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)xs]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.xs).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(500) // xs
|
||||
expect(Screen.xs).toBe(true)
|
||||
|
||||
setWidth(800) // sm
|
||||
expect(Screen.xs).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)sm]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.sm).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(500) // xs
|
||||
expect(Screen.sm).toBe(false)
|
||||
|
||||
setWidth(800) // sm
|
||||
expect(Screen.sm).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)md]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.md).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(800) // sm
|
||||
expect(Screen.md).toBe(false)
|
||||
|
||||
setWidth(1200) // md
|
||||
expect(Screen.md).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)lg]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.lg).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(1200) // md
|
||||
expect(Screen.lg).toBe(false)
|
||||
|
||||
setWidth(1600) // lg
|
||||
expect(Screen.lg).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(prop)xl]', () => {
|
||||
test('is correct type', () => {
|
||||
mountPlugin()
|
||||
expect(Screen.xl).toBeTypeOf('boolean')
|
||||
})
|
||||
|
||||
test('is reactive', () => {
|
||||
mountPlugin()
|
||||
|
||||
setWidth(1600) // lg
|
||||
expect(Screen.xl).toBe(false)
|
||||
|
||||
setWidth(2000) // xl
|
||||
expect(Screen.xl).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)setSizes]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
const newSizes = {
|
||||
sm: 10,
|
||||
md: 15,
|
||||
lg: 20,
|
||||
xl: 25
|
||||
}
|
||||
|
||||
expect(
|
||||
Screen.setSizes(newSizes)
|
||||
).toBeUndefined()
|
||||
|
||||
expect(
|
||||
Screen.sizes
|
||||
).toStrictEqual(newSizes)
|
||||
|
||||
setWidth(5)
|
||||
expect(Screen).toMatchObject({
|
||||
name: 'xs',
|
||||
xs: true,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: false,
|
||||
lt: {
|
||||
sm: true,
|
||||
md: true,
|
||||
lg: true,
|
||||
xl: true
|
||||
},
|
||||
gt: {
|
||||
xs: false,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false
|
||||
}
|
||||
})
|
||||
|
||||
setWidth(11)
|
||||
expect(Screen).toMatchObject({
|
||||
name: 'sm',
|
||||
xs: false,
|
||||
sm: true,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: false,
|
||||
lt: {
|
||||
sm: false,
|
||||
md: true,
|
||||
lg: true,
|
||||
xl: true
|
||||
},
|
||||
gt: {
|
||||
xs: true,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false
|
||||
}
|
||||
})
|
||||
|
||||
setWidth(16)
|
||||
expect(Screen).toMatchObject({
|
||||
name: 'md',
|
||||
xs: false,
|
||||
sm: false,
|
||||
md: true,
|
||||
lg: false,
|
||||
xl: false,
|
||||
lt: {
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: true,
|
||||
xl: true
|
||||
},
|
||||
gt: {
|
||||
xs: true,
|
||||
sm: true,
|
||||
md: false,
|
||||
lg: false
|
||||
}
|
||||
})
|
||||
|
||||
setWidth(21)
|
||||
expect(Screen).toMatchObject({
|
||||
name: 'lg',
|
||||
xs: false,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: true,
|
||||
xl: false,
|
||||
lt: {
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: true
|
||||
},
|
||||
gt: {
|
||||
xs: true,
|
||||
sm: true,
|
||||
md: true,
|
||||
lg: false
|
||||
}
|
||||
})
|
||||
|
||||
setWidth(26)
|
||||
expect(Screen).toMatchObject({
|
||||
name: 'xl',
|
||||
xs: false,
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: true,
|
||||
lt: {
|
||||
sm: false,
|
||||
md: false,
|
||||
lg: false,
|
||||
xl: false
|
||||
},
|
||||
gt: {
|
||||
xs: true,
|
||||
sm: true,
|
||||
md: true,
|
||||
lg: true
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)setDebounce]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
expect(
|
||||
Screen.setDebounce(1000)
|
||||
).toBeUndefined()
|
||||
|
||||
window.innerWidth = 100
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
|
||||
expect(Screen.width).not.toBe(100)
|
||||
vi.advanceTimersByTime(999)
|
||||
expect(Screen.width).not.toBe(100)
|
||||
vi.advanceTimersByTime(1)
|
||||
expect(Screen.width).toBe(100)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
16
Frontend-Learner/node_modules/quasar/src/plugins/storage/LocalStorage.js
generated
vendored
Normal file
16
Frontend-Learner/node_modules/quasar/src/plugins/storage/LocalStorage.js
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { client } from '../platform/Platform.js'
|
||||
import { getEmptyStorage, getStorage } from './engine/web-storage.js'
|
||||
|
||||
const storage = __QUASAR_SSR_SERVER__ || client.has.webStorage === false
|
||||
? getEmptyStorage()
|
||||
: getStorage('local')
|
||||
|
||||
const Plugin = {
|
||||
install ({ $q }) {
|
||||
$q.localStorage = storage
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(Plugin, storage)
|
||||
|
||||
export default Plugin
|
||||
5
Frontend-Learner/node_modules/quasar/src/plugins/storage/LocalStorage.json
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/plugins/storage/LocalStorage.json
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"mixins": [ "plugins/storage/engine/web-storage" ],
|
||||
|
||||
"injection": "$q.localStorage"
|
||||
}
|
||||
323
Frontend-Learner/node_modules/quasar/src/plugins/storage/LocalStorage.test.js
generated
vendored
Normal file
323
Frontend-Learner/node_modules/quasar/src/plugins/storage/LocalStorage.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
import { mount, config } from '@vue/test-utils'
|
||||
|
||||
import LocalStorage from './LocalStorage.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
// We override Quasar install so it installs this plugin
|
||||
const quasarVuePlugin = config.global.plugins.find(entry => entry.name === 'Quasar')
|
||||
const { install } = quasarVuePlugin
|
||||
quasarVuePlugin.install = app => install(app, { plugins: { LocalStorage } })
|
||||
|
||||
describe('[LocalStorage API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
|
||||
expect($q.localStorage).toBeDefined()
|
||||
expect($q.localStorage).toBeTypeOf('object')
|
||||
expect(Object.keys($q.localStorage)).not.toHaveLength(0)
|
||||
|
||||
expect(LocalStorage).toMatchObject($q.localStorage)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)hasItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(LocalStorage.hasItem('has')).toBe(false)
|
||||
LocalStorage.setItem('has', 'rstoenescu')
|
||||
expect(LocalStorage.hasItem('has')).toBe(true)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.hasItem).toBe(LocalStorage.hasItem)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getLength]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
const len = LocalStorage.getLength()
|
||||
expect(len).toBeTypeOf('number')
|
||||
|
||||
LocalStorage.setItem('getLength', 0)
|
||||
expect(LocalStorage.getLength()).toBe(len + 1)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.getLength).toBe(LocalStorage.getLength)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(
|
||||
LocalStorage.getItem('getItem')
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.getItem).toBe(LocalStorage.getItem)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getIndex]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
LocalStorage.setItem('getIndex', 'rstoenescu')
|
||||
|
||||
expect(
|
||||
LocalStorage.getIndex(0)
|
||||
).$any([
|
||||
expect.any(Number),
|
||||
expect.any(Boolean),
|
||||
expect.any(Date),
|
||||
expect.any(RegExp),
|
||||
expect.any(Function),
|
||||
expect.any(Object),
|
||||
expect.any(Array),
|
||||
expect.any(String)
|
||||
])
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.getIndex).toBe(LocalStorage.getIndex)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getKey]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
LocalStorage.setItem('getKey', 'rstoenescu')
|
||||
|
||||
expect(
|
||||
LocalStorage.getKey(0)
|
||||
).toBeTypeOf('string')
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.getKey).toBe(LocalStorage.getKey)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getAll]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
LocalStorage.setItem('getAll', 'rstoenescu')
|
||||
|
||||
const result = LocalStorage.getAll()
|
||||
expect(result).toBeTypeOf('object')
|
||||
expect(Object.keys(result)).not.toHaveLength(0)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.getAll).toBe(LocalStorage.getAll)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getAllKeys]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
LocalStorage.setItem('getAllKeys', 'rstoenescu')
|
||||
|
||||
expect(
|
||||
Array.isArray(LocalStorage.getAllKeys())
|
||||
).toBe(true)
|
||||
|
||||
expect(
|
||||
LocalStorage.getAllKeys()
|
||||
).toContain('getAllKeys')
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.getAllKeys).toBe(LocalStorage.getAllKeys)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)setItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(
|
||||
LocalStorage.setItem('set', 'rstoenescu')
|
||||
).toBeUndefined()
|
||||
|
||||
expect(
|
||||
LocalStorage.getItem('set')
|
||||
).toBe('rstoenescu')
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.setItem).toBe(LocalStorage.setItem)
|
||||
})
|
||||
|
||||
test('can override value', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(LocalStorage.setItem('set2', 'rstoenescu'))
|
||||
expect(LocalStorage.getItem('set2')).toBe('rstoenescu')
|
||||
|
||||
expect(LocalStorage.setItem('set2', 'rstoenescu2'))
|
||||
expect(LocalStorage.getItem('set2')).toBe('rstoenescu2')
|
||||
})
|
||||
|
||||
test('can encode + decode a Number', () => {
|
||||
mountPlugin()
|
||||
|
||||
LocalStorage.setItem('Number', 123)
|
||||
expect(LocalStorage.getItem('Number')).toBe(123)
|
||||
})
|
||||
|
||||
test('can encode + decode a Boolean', () => {
|
||||
mountPlugin()
|
||||
|
||||
LocalStorage.setItem('Boolean', true)
|
||||
expect(LocalStorage.getItem('Boolean')).toBe(true)
|
||||
})
|
||||
|
||||
test('can encode + decode a Date', () => {
|
||||
mountPlugin()
|
||||
const date = new Date()
|
||||
|
||||
LocalStorage.setItem('Date', date)
|
||||
expect(
|
||||
LocalStorage.getItem('Date')
|
||||
).toStrictEqual(date)
|
||||
})
|
||||
|
||||
test('can encode + decode a String', () => {
|
||||
mountPlugin()
|
||||
|
||||
LocalStorage.setItem('String', 'rstoenescu')
|
||||
expect(
|
||||
LocalStorage.getItem('String')
|
||||
).toBe('rstoenescu')
|
||||
})
|
||||
|
||||
test('can encode + decode a RegExp', () => {
|
||||
mountPlugin()
|
||||
|
||||
LocalStorage.setItem('RegExp', /abc/)
|
||||
expect(
|
||||
LocalStorage.getItem('RegExp')
|
||||
).toStrictEqual(/abc/)
|
||||
})
|
||||
|
||||
test('can encode + decode a Function', () => {
|
||||
mountPlugin()
|
||||
const fn = () => 5
|
||||
|
||||
LocalStorage.setItem('Function', fn)
|
||||
expect(
|
||||
LocalStorage.getItem('Function')
|
||||
).toBe(fn.toString())
|
||||
})
|
||||
|
||||
test('can encode + decode an Object', () => {
|
||||
mountPlugin()
|
||||
const obj = { a: 1 }
|
||||
|
||||
LocalStorage.setItem('Object', obj)
|
||||
expect(
|
||||
LocalStorage.getItem('Object')
|
||||
).toStrictEqual(obj)
|
||||
})
|
||||
|
||||
test('can encode + decode an Array', () => {
|
||||
mountPlugin()
|
||||
const arr = [ 1, 2, 3 ]
|
||||
|
||||
LocalStorage.setItem('Array', arr)
|
||||
expect(
|
||||
LocalStorage.getItem('Array')
|
||||
).toStrictEqual(arr)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)removeItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
LocalStorage.setItem('remove', 5)
|
||||
expect(
|
||||
LocalStorage.getItem('remove')
|
||||
).toBe(5)
|
||||
|
||||
expect(
|
||||
LocalStorage.removeItem('remove')
|
||||
).toBeUndefined()
|
||||
|
||||
expect(
|
||||
LocalStorage.getItem('remove')
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.removeItem).toBe(LocalStorage.removeItem)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)clear]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
LocalStorage.setItem('clear', 5)
|
||||
expect(LocalStorage.getItem('clear')).toBe(5)
|
||||
|
||||
expect(LocalStorage.clear()).toBeUndefined()
|
||||
|
||||
expect(LocalStorage.getItem('clear')).toBeNull()
|
||||
expect(LocalStorage.getLength()).toBe(0)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.clear).toBe(LocalStorage.clear)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)isEmpty]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
LocalStorage.setItem('isEmpty', 5)
|
||||
expect(LocalStorage.getItem('isEmpty')).toBe(5)
|
||||
|
||||
expect(LocalStorage.isEmpty()).toBe(false)
|
||||
|
||||
LocalStorage.clear()
|
||||
|
||||
expect(LocalStorage.isEmpty()).toBe(true)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.localStorage.isEmpty).toBe(LocalStorage.isEmpty)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
16
Frontend-Learner/node_modules/quasar/src/plugins/storage/SessionStorage.js
generated
vendored
Normal file
16
Frontend-Learner/node_modules/quasar/src/plugins/storage/SessionStorage.js
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { client } from '../platform/Platform.js'
|
||||
import { getEmptyStorage, getStorage } from './engine/web-storage.js'
|
||||
|
||||
const storage = __QUASAR_SSR_SERVER__ || client.has.webStorage === false
|
||||
? getEmptyStorage()
|
||||
: getStorage('session')
|
||||
|
||||
const Plugin = {
|
||||
install ({ $q }) {
|
||||
$q.sessionStorage = storage
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(Plugin, storage)
|
||||
|
||||
export default Plugin
|
||||
5
Frontend-Learner/node_modules/quasar/src/plugins/storage/SessionStorage.json
generated
vendored
Normal file
5
Frontend-Learner/node_modules/quasar/src/plugins/storage/SessionStorage.json
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"mixins": [ "plugins/storage/engine/web-storage" ],
|
||||
|
||||
"injection": "$q.sessionStorage"
|
||||
}
|
||||
323
Frontend-Learner/node_modules/quasar/src/plugins/storage/SessionStorage.test.js
generated
vendored
Normal file
323
Frontend-Learner/node_modules/quasar/src/plugins/storage/SessionStorage.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
import { mount, config } from '@vue/test-utils'
|
||||
|
||||
import SessionStorage from './SessionStorage.js'
|
||||
|
||||
const mountPlugin = () => mount({ template: '<div />' })
|
||||
|
||||
// We override Quasar install so it installs this plugin
|
||||
const quasarVuePlugin = config.global.plugins.find(entry => entry.name === 'Quasar')
|
||||
const { install } = quasarVuePlugin
|
||||
quasarVuePlugin.install = app => install(app, { plugins: { SessionStorage } })
|
||||
|
||||
describe('[SessionStorage API]', () => {
|
||||
describe('[Injection]', () => {
|
||||
test('is injected into $q', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
|
||||
expect($q.sessionStorage).toBeDefined()
|
||||
expect($q.sessionStorage).toBeTypeOf('object')
|
||||
expect(Object.keys($q.sessionStorage)).not.toHaveLength(0)
|
||||
|
||||
expect(SessionStorage).toMatchObject($q.sessionStorage)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[Methods]', () => {
|
||||
describe('[(method)hasItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(SessionStorage.hasItem('has')).toBe(false)
|
||||
SessionStorage.setItem('has', 'rstoenescu')
|
||||
expect(SessionStorage.hasItem('has')).toBe(true)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.hasItem).toBe(SessionStorage.hasItem)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getLength]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
const len = SessionStorage.getLength()
|
||||
expect(len).toBeTypeOf('number')
|
||||
|
||||
SessionStorage.setItem('getLength', 0)
|
||||
expect(SessionStorage.getLength()).toBe(len + 1)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.getLength).toBe(SessionStorage.getLength)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(
|
||||
SessionStorage.getItem('getItem')
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.getItem).toBe(SessionStorage.getItem)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getIndex]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
SessionStorage.setItem('getIndex', 'rstoenescu')
|
||||
|
||||
expect(
|
||||
SessionStorage.getIndex(0)
|
||||
).$any([
|
||||
expect.any(Number),
|
||||
expect.any(Boolean),
|
||||
expect.any(Date),
|
||||
expect.any(RegExp),
|
||||
expect.any(Function),
|
||||
expect.any(Object),
|
||||
expect.any(Array),
|
||||
expect.any(String)
|
||||
])
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.getIndex).toBe(SessionStorage.getIndex)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getKey]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
SessionStorage.setItem('getKey', 'rstoenescu')
|
||||
|
||||
expect(
|
||||
SessionStorage.getKey(0)
|
||||
).toBeTypeOf('string')
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.getKey).toBe(SessionStorage.getKey)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getAll]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
SessionStorage.setItem('getAll', 'rstoenescu')
|
||||
|
||||
const result = SessionStorage.getAll()
|
||||
expect(result).toBeTypeOf('object')
|
||||
expect(Object.keys(result)).not.toHaveLength(0)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.getAll).toBe(SessionStorage.getAll)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)getAllKeys]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
// ensure at least one element is defined
|
||||
SessionStorage.setItem('getAllKeys', 'rstoenescu')
|
||||
|
||||
expect(
|
||||
Array.isArray(SessionStorage.getAllKeys())
|
||||
).toBe(true)
|
||||
|
||||
expect(
|
||||
SessionStorage.getAllKeys()
|
||||
).toContain('getAllKeys')
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.getAllKeys).toBe(SessionStorage.getAllKeys)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)setItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(
|
||||
SessionStorage.setItem('set', 'rstoenescu')
|
||||
).toBeUndefined()
|
||||
|
||||
expect(
|
||||
SessionStorage.getItem('set')
|
||||
).toBe('rstoenescu')
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.setItem).toBe(SessionStorage.setItem)
|
||||
})
|
||||
|
||||
test('can override value', () => {
|
||||
mountPlugin()
|
||||
|
||||
expect(SessionStorage.setItem('set2', 'rstoenescu'))
|
||||
expect(SessionStorage.getItem('set2')).toBe('rstoenescu')
|
||||
|
||||
expect(SessionStorage.setItem('set2', 'rstoenescu2'))
|
||||
expect(SessionStorage.getItem('set2')).toBe('rstoenescu2')
|
||||
})
|
||||
|
||||
test('can encode + decode a Number', () => {
|
||||
mountPlugin()
|
||||
|
||||
SessionStorage.setItem('Number', 123)
|
||||
expect(SessionStorage.getItem('Number')).toBe(123)
|
||||
})
|
||||
|
||||
test('can encode + decode a Boolean', () => {
|
||||
mountPlugin()
|
||||
|
||||
SessionStorage.setItem('Boolean', true)
|
||||
expect(SessionStorage.getItem('Boolean')).toBe(true)
|
||||
})
|
||||
|
||||
test('can encode + decode a Date', () => {
|
||||
mountPlugin()
|
||||
const date = new Date()
|
||||
|
||||
SessionStorage.setItem('Date', date)
|
||||
expect(
|
||||
SessionStorage.getItem('Date')
|
||||
).toStrictEqual(date)
|
||||
})
|
||||
|
||||
test('can encode + decode a String', () => {
|
||||
mountPlugin()
|
||||
|
||||
SessionStorage.setItem('String', 'rstoenescu')
|
||||
expect(
|
||||
SessionStorage.getItem('String')
|
||||
).toBe('rstoenescu')
|
||||
})
|
||||
|
||||
test('can encode + decode a RegExp', () => {
|
||||
mountPlugin()
|
||||
|
||||
SessionStorage.setItem('RegExp', /abc/)
|
||||
expect(
|
||||
SessionStorage.getItem('RegExp')
|
||||
).toStrictEqual(/abc/)
|
||||
})
|
||||
|
||||
test('can encode + decode a Function', () => {
|
||||
mountPlugin()
|
||||
const fn = () => 5
|
||||
|
||||
SessionStorage.setItem('Function', fn)
|
||||
expect(
|
||||
SessionStorage.getItem('Function')
|
||||
).toBe(fn.toString())
|
||||
})
|
||||
|
||||
test('can encode + decode an Object', () => {
|
||||
mountPlugin()
|
||||
const obj = { a: 1 }
|
||||
|
||||
SessionStorage.setItem('Object', obj)
|
||||
expect(
|
||||
SessionStorage.getItem('Object')
|
||||
).toStrictEqual(obj)
|
||||
})
|
||||
|
||||
test('can encode + decode an Array', () => {
|
||||
mountPlugin()
|
||||
const arr = [ 1, 2, 3 ]
|
||||
|
||||
SessionStorage.setItem('Array', arr)
|
||||
expect(
|
||||
SessionStorage.getItem('Array')
|
||||
).toStrictEqual(arr)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)removeItem]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
SessionStorage.setItem('remove', 5)
|
||||
expect(
|
||||
SessionStorage.getItem('remove')
|
||||
).toBe(5)
|
||||
|
||||
expect(
|
||||
SessionStorage.removeItem('remove')
|
||||
).toBeUndefined()
|
||||
|
||||
expect(
|
||||
SessionStorage.getItem('remove')
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.removeItem).toBe(SessionStorage.removeItem)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)clear]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
SessionStorage.setItem('clear', 5)
|
||||
expect(SessionStorage.getItem('clear')).toBe(5)
|
||||
|
||||
expect(SessionStorage.clear()).toBeUndefined()
|
||||
|
||||
expect(SessionStorage.getItem('clear')).toBeNull()
|
||||
expect(SessionStorage.getLength()).toBe(0)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.clear).toBe(SessionStorage.clear)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(method)isEmpty]', () => {
|
||||
test('should be callable', () => {
|
||||
mountPlugin()
|
||||
|
||||
SessionStorage.setItem('isEmpty', 5)
|
||||
expect(SessionStorage.getItem('isEmpty')).toBe(5)
|
||||
|
||||
expect(SessionStorage.isEmpty()).toBe(false)
|
||||
|
||||
SessionStorage.clear()
|
||||
|
||||
expect(SessionStorage.isEmpty()).toBe(true)
|
||||
})
|
||||
|
||||
test('matches $q API', () => {
|
||||
const { vm: { $q } } = mountPlugin()
|
||||
expect($q.sessionStorage.isEmpty).toBe(SessionStorage.isEmpty)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
147
Frontend-Learner/node_modules/quasar/src/plugins/storage/engine/web-storage.js
generated
vendored
Normal file
147
Frontend-Learner/node_modules/quasar/src/plugins/storage/engine/web-storage.js
generated
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
import { noop } from '../../../utils/event/event.js'
|
||||
import { isDate, isRegexp } from '../../../utils/is/is.js'
|
||||
|
||||
function encode (value) {
|
||||
if (isDate(value) === true) {
|
||||
return '__q_date|' + value.getTime()
|
||||
}
|
||||
if (isRegexp(value) === true) {
|
||||
return '__q_expr|' + value.source
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
return '__q_numb|' + value
|
||||
}
|
||||
if (typeof value === 'boolean') {
|
||||
return '__q_bool|' + (value ? '1' : '0')
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return '__q_strn|' + value
|
||||
}
|
||||
if (typeof value === 'function') {
|
||||
return '__q_strn|' + value.toString()
|
||||
}
|
||||
if (value === Object(value)) {
|
||||
return '__q_objt|' + JSON.stringify(value)
|
||||
}
|
||||
|
||||
// hmm, we don't know what to do with it,
|
||||
// so just return it as is
|
||||
return value
|
||||
}
|
||||
|
||||
function decode (value) {
|
||||
const length = value.length
|
||||
if (length < 9) {
|
||||
// then it wasn't encoded by us
|
||||
return value
|
||||
}
|
||||
|
||||
const type = value.substring(0, 8)
|
||||
const source = value.substring(9)
|
||||
|
||||
switch (type) {
|
||||
case '__q_date':
|
||||
const number = Number(source)
|
||||
return new Date(Number.isNaN(number) === true ? source : number)
|
||||
|
||||
case '__q_expr':
|
||||
return new RegExp(source)
|
||||
|
||||
case '__q_numb':
|
||||
return Number(source)
|
||||
|
||||
case '__q_bool':
|
||||
return Boolean(source === '1')
|
||||
|
||||
case '__q_strn':
|
||||
return '' + source
|
||||
|
||||
case '__q_objt':
|
||||
return JSON.parse(source)
|
||||
|
||||
default:
|
||||
// hmm, we reached here, we don't know the type,
|
||||
// then it means it wasn't encoded by us, so just
|
||||
// return whatever value it is
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
export function getEmptyStorage () {
|
||||
const getVal = () => null
|
||||
|
||||
return {
|
||||
has: () => false, // alias for hasItem; TODO: remove in Qv3
|
||||
hasItem: () => false,
|
||||
getLength: () => 0,
|
||||
getItem: getVal,
|
||||
getIndex: getVal,
|
||||
getKey: getVal,
|
||||
getAll: () => {},
|
||||
getAllKeys: () => [],
|
||||
set: noop, // alias for setItem; TODO: remove in Qv3
|
||||
setItem: noop,
|
||||
remove: noop, // alias for removeItem; TODO: remove in Qv3
|
||||
removeItem: noop,
|
||||
clear: noop,
|
||||
isEmpty: () => true
|
||||
}
|
||||
}
|
||||
|
||||
export function getStorage (type) {
|
||||
const
|
||||
webStorage = window[ type + 'Storage' ],
|
||||
get = key => {
|
||||
const item = webStorage.getItem(key)
|
||||
return item
|
||||
? decode(item)
|
||||
: null
|
||||
}
|
||||
|
||||
const hasItem = key => webStorage.getItem(key) !== null
|
||||
const setItem = (key, value) => { webStorage.setItem(key, encode(value)) }
|
||||
const removeItem = key => { webStorage.removeItem(key) }
|
||||
|
||||
return {
|
||||
has: hasItem, // TODO: remove in Qv3
|
||||
hasItem,
|
||||
getLength: () => webStorage.length,
|
||||
getItem: get,
|
||||
getIndex: index => {
|
||||
return index < webStorage.length
|
||||
? get(webStorage.key(index))
|
||||
: null
|
||||
},
|
||||
getKey: index => {
|
||||
return index < webStorage.length
|
||||
? webStorage.key(index)
|
||||
: null
|
||||
},
|
||||
getAll: () => {
|
||||
let key
|
||||
const result = {}, len = webStorage.length
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
key = webStorage.key(i)
|
||||
result[ key ] = get(key)
|
||||
}
|
||||
|
||||
return result
|
||||
},
|
||||
getAllKeys: () => {
|
||||
const result = [], len = webStorage.length
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
result.push(webStorage.key(i))
|
||||
}
|
||||
|
||||
return result
|
||||
},
|
||||
set: setItem, // TODO: remove in Qv3
|
||||
setItem,
|
||||
remove: removeItem, // TODO: remove in Qv3
|
||||
removeItem,
|
||||
clear: () => { webStorage.clear() },
|
||||
isEmpty: () => webStorage.length === 0
|
||||
}
|
||||
}
|
||||
165
Frontend-Learner/node_modules/quasar/src/plugins/storage/engine/web-storage.json
generated
vendored
Normal file
165
Frontend-Learner/node_modules/quasar/src/plugins/storage/engine/web-storage.json
generated
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
{
|
||||
"meta": {
|
||||
"docsUrl": "https://v2.quasar.dev/quasar-plugins/web-storage"
|
||||
},
|
||||
|
||||
"methods": {
|
||||
"hasItem": {
|
||||
"desc": "Check if storage item exists",
|
||||
"alias": "has",
|
||||
"params": {
|
||||
"key": {
|
||||
"type": "String",
|
||||
"desc": "Entry key",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "Does the item exists or not?"
|
||||
}
|
||||
},
|
||||
|
||||
"getLength": {
|
||||
"desc": "Get storage number of entries",
|
||||
"params": null,
|
||||
"returns": {
|
||||
"type": "Number",
|
||||
"desc": "Number of entries"
|
||||
}
|
||||
},
|
||||
|
||||
"getItem": {
|
||||
"tsType": "WebStorageGetItemMethodType",
|
||||
"desc": "Get a storage item value",
|
||||
"params": {
|
||||
"key": {
|
||||
"type": "String",
|
||||
"desc": "Entry key",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": [ "Number", "Boolean", "Date", "RegExp", "Function", "Object", "Array", "String", "null" ],
|
||||
"desc": "Storage item value",
|
||||
"examples": [ "'john12'", "702" ]
|
||||
}
|
||||
},
|
||||
|
||||
"getIndex": {
|
||||
"tsType": "WebStorageGetIndexMethodType",
|
||||
"desc": "Get the storage item value at specific index",
|
||||
"params": {
|
||||
"index": {
|
||||
"type": "Number",
|
||||
"desc": "Entry index",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": [ "Number", "Boolean", "Date", "RegExp", "Function", "Object", "Array", "String", "null" ],
|
||||
"desc": "Storage item index"
|
||||
}
|
||||
},
|
||||
|
||||
"getKey": {
|
||||
"tsType": "WebStorageGetKeyMethodType",
|
||||
"desc": "Get the storage key at specific index",
|
||||
"params": {
|
||||
"index": {
|
||||
"type": "Number",
|
||||
"desc": "Entry index",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": [ "String", "null" ],
|
||||
"desc": "Storage key",
|
||||
"examples": [ "'userId'" ]
|
||||
}
|
||||
},
|
||||
|
||||
"getAll": {
|
||||
"desc": "Retrieve all items in storage",
|
||||
"params": null,
|
||||
"returns": {
|
||||
"type": "Object",
|
||||
"desc": "Object syntax: item name as Object key and its value",
|
||||
"examples": [ "{ userId: 'rstoenescu', timesLoggedIn: 14 }" ]
|
||||
}
|
||||
},
|
||||
|
||||
"getAllKeys": {
|
||||
"tsType": "WebStorageGetAllKeysMethodType",
|
||||
"desc": "Retrieve all keys in storage",
|
||||
"params": null,
|
||||
"returns": {
|
||||
"type": "Array",
|
||||
"desc": "Storage keys (Array of Strings)",
|
||||
"examples": [ "[ 'userId', 'password' ]" ]
|
||||
}
|
||||
},
|
||||
|
||||
"setItem": {
|
||||
"desc": "Set item in storage",
|
||||
"alias": "set",
|
||||
"params": {
|
||||
"key": {
|
||||
"type": "String",
|
||||
"desc": "Entry key",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
},
|
||||
|
||||
"value": {
|
||||
"type": [ "Number", "Boolean", "Date", "RegExp", "Function", "Object", "Array", "String", "null" ],
|
||||
"desc": "Entry value",
|
||||
"required": true,
|
||||
"params": {
|
||||
"...params": {
|
||||
"type": "Any",
|
||||
"__exemption": [ "desc" ]
|
||||
}
|
||||
},
|
||||
"returns": {
|
||||
"type": "Any",
|
||||
"__exemption": [ "desc" ]
|
||||
},
|
||||
"examples": [ "'john12'" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"removeItem": {
|
||||
"desc": "Remove a storage item",
|
||||
"alias": "remove",
|
||||
"params": {
|
||||
"key": {
|
||||
"type": "String",
|
||||
"desc": "Storage key",
|
||||
"required": true,
|
||||
"examples": [ "'userId'" ]
|
||||
}
|
||||
},
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"clear": {
|
||||
"desc": "Remove everything from the storage",
|
||||
"params": null,
|
||||
"returns": null
|
||||
},
|
||||
|
||||
"isEmpty": {
|
||||
"desc": "Determine if storage has any items",
|
||||
"params": null,
|
||||
"returns": {
|
||||
"type": "Boolean",
|
||||
"desc": "Tells if storage is empty or not"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Frontend-Learner/node_modules/quasar/src/plugins/storage/engine/web-storage.test.js
generated
vendored
Normal file
43
Frontend-Learner/node_modules/quasar/src/plugins/storage/engine/web-storage.test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { describe, test, expect } from 'vitest'
|
||||
|
||||
import { getEmptyStorage, getStorage } from './web-storage.js'
|
||||
|
||||
const objectDefinition = {
|
||||
has: expect.any(Function), // alias of has
|
||||
hasItem: expect.any(Function),
|
||||
getLength: expect.any(Function),
|
||||
getItem: expect.any(Function),
|
||||
getIndex: expect.any(Function),
|
||||
getKey: expect.any(Function),
|
||||
getAll: expect.any(Function),
|
||||
getAllKeys: expect.any(Function),
|
||||
set: expect.any(Function), // alias of setItem
|
||||
setItem: expect.any(Function),
|
||||
remove: expect.any(Function), // alias of removeItem
|
||||
removeItem: expect.any(Function),
|
||||
clear: expect.any(Function),
|
||||
isEmpty: expect.any(Function)
|
||||
}
|
||||
|
||||
describe('[webStorage API]', () => {
|
||||
describe('[Functions]', () => {
|
||||
describe('[(function)getEmptyStorage]', () => {
|
||||
test('has correct return value', () => {
|
||||
const result = getEmptyStorage()
|
||||
expect(result).toStrictEqual(objectDefinition)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[(function)getStorage]', () => {
|
||||
test('has correct return value for local', () => {
|
||||
const local = getStorage('local')
|
||||
expect(local).toStrictEqual(objectDefinition)
|
||||
})
|
||||
|
||||
test('has correct return value for session', () => {
|
||||
const session = getStorage('session')
|
||||
expect(session).toStrictEqual(objectDefinition)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue