一大波更新
parent
eab9de2c2c
commit
0c42d793fa
|
@ -1,10 +1,11 @@
|
||||||
*.min.js
|
*.min.js
|
||||||
.httpserver
|
.httpserver
|
||||||
index.html
|
index.html
|
||||||
test.js
|
app.js
|
||||||
.vscode
|
.vscode
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
|
test
|
||||||
*.sublime-project
|
*.sublime-project
|
||||||
*.sublime-workspace
|
*.sublime-workspace
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* {wkitd}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/08/10 10:02:15
|
||||||
|
*/
|
||||||
|
|
||||||
|
import './init.js'
|
||||||
|
import { html, css, Component } from 'wkit'
|
||||||
|
import { noop } from './utils.js'
|
||||||
|
|
||||||
|
export * from './router/index.js'
|
||||||
|
export { createStore } from './store.js'
|
||||||
|
|
||||||
|
class App extends Component {}
|
||||||
|
|
||||||
|
export function createApp({
|
||||||
|
data = {},
|
||||||
|
methods = {},
|
||||||
|
mounted = noop,
|
||||||
|
render
|
||||||
|
} = {}) {
|
||||||
|
//
|
||||||
|
|
||||||
|
return new (function () {
|
||||||
|
App.props = data
|
||||||
|
Object.assign(App.prototype, methods, { mounted })
|
||||||
|
|
||||||
|
this.use = function (plugin = noop, ...args) {
|
||||||
|
plugin.apply(this, args)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
this.mount = function () {
|
||||||
|
let $router = window.__wkitd__.get('$router')
|
||||||
|
if (render) {
|
||||||
|
App.prototype.render = render
|
||||||
|
} else {
|
||||||
|
if ($router) {
|
||||||
|
App.prototype.render = function () {
|
||||||
|
return html`<router-view></router-view>`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
App.styles = css`
|
||||||
|
:host {
|
||||||
|
font-family: monospace;
|
||||||
|
color: #647889;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
margin: 16px 0;
|
||||||
|
background: #f7f8fb;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
App.prototype.render = function () {
|
||||||
|
return html`
|
||||||
|
<h1>It works!!!</h1>
|
||||||
|
<cite>
|
||||||
|
If you don't use router, you may define the
|
||||||
|
<b>render</b> property.
|
||||||
|
</cite>
|
||||||
|
<div class="code">
|
||||||
|
<pre><code> createApp({</code></pre>
|
||||||
|
<pre><code> render() {</code></pre>
|
||||||
|
<pre><code> return html\`<wc-home></wc-home>\`</code></pre>
|
||||||
|
<pre><code> }</code></pre>
|
||||||
|
<pre><code> })</code></pre>
|
||||||
|
<pre><code> .mount()</code></pre>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($router) {
|
||||||
|
App.prototype.mounted = function (...args) {
|
||||||
|
let $view = window.__wkitd__.get('ROUTER_VIEW')
|
||||||
|
$view.sync($router.getViews())
|
||||||
|
$router.init()
|
||||||
|
mounted.call(this, ...args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
App.reg('app')
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/08/10 10:19:12
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { hideProp } from './utils.js'
|
||||||
|
|
||||||
|
hideProp(window, '__wkitd__', new Map())
|
|
@ -0,0 +1,179 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-14 21:04:50
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import { bind, fire } from 'wkit'
|
||||||
|
import { hideProp, targetIsThisWindow } from '../utils.js'
|
||||||
|
|
||||||
|
//hash前缀正则
|
||||||
|
const PREFIX_REGEXP = /^(#!|#)[\/]?/
|
||||||
|
const TRIM_REGEXP = /(^[/]+)|([/]+$)/g
|
||||||
|
const DEFAULT_OPTIONS = {
|
||||||
|
prefix: '!/',
|
||||||
|
allowReload: true //连续点击同一个链接是否重新加载
|
||||||
|
}
|
||||||
|
|
||||||
|
const RULE_REGEXP =
|
||||||
|
/(:id)|(\{id\})|(\{id:([A-z\d\,\[\]\{\}\-\+\*\?\!:\^\$]*)\})/g
|
||||||
|
|
||||||
|
const __ready__ = Symbol('ready')
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
[__ready__] = false
|
||||||
|
|
||||||
|
#tables = new Map()
|
||||||
|
#views = new Set()
|
||||||
|
|
||||||
|
#options = Object.create(null)
|
||||||
|
|
||||||
|
#route = Object.create(null)
|
||||||
|
|
||||||
|
constructor(options = {}) {
|
||||||
|
Object.assign(this.#options, DEFAULT_OPTIONS, options)
|
||||||
|
|
||||||
|
bind(window, 'load, popstate', this.#hashchange.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
get route() {
|
||||||
|
return this.#route
|
||||||
|
}
|
||||||
|
|
||||||
|
#hashchange(ev) {
|
||||||
|
if (ev?.type === 'load') {
|
||||||
|
if (this[__ready__]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this[__ready__] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = location.hash
|
||||||
|
|
||||||
|
path = path.replace(PREFIX_REGEXP, '').trim()
|
||||||
|
path = path.replace(TRIM_REGEXP, '')
|
||||||
|
|
||||||
|
if (ev?.type === 'load') {
|
||||||
|
this.go(path)
|
||||||
|
// hash模式要手动触发一下路由检测
|
||||||
|
this.#check(path)
|
||||||
|
} else {
|
||||||
|
this.#check(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#parseRule(route) {
|
||||||
|
if (route.path === '!') {
|
||||||
|
route.regexp = null
|
||||||
|
} else {
|
||||||
|
let re = route.path.replace(RULE_REGEXP, function (m, p1, p2, p3, p4) {
|
||||||
|
let w = '([\\w.-]'
|
||||||
|
if (p1 || p2) {
|
||||||
|
return w + '+)'
|
||||||
|
} else {
|
||||||
|
if (!/^\{[\d\,]+\}$/.test(p4)) {
|
||||||
|
w = '('
|
||||||
|
}
|
||||||
|
return w + p4 + ')'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
re = re
|
||||||
|
.replace(/(([^\\])([\/]+))/g, '$2\\/')
|
||||||
|
.replace(/(([^\\])([\.]+))/g, '$2\\.')
|
||||||
|
.replace(/(([^\\])([\-]+))/g, '$2\\-')
|
||||||
|
.replace(/(\(.*)(\\[\-]+)(.*\))/g, '$1-$3')
|
||||||
|
re = '^' + re + '$'
|
||||||
|
route.regexp = new RegExp(re)
|
||||||
|
}
|
||||||
|
return route
|
||||||
|
}
|
||||||
|
|
||||||
|
#add(route) {
|
||||||
|
// 特殊值"!", 则自动作非匹配回调处理
|
||||||
|
// if (route.path === '!') {
|
||||||
|
// // this.noMatch = callback
|
||||||
|
// this.#views.add(route.name)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
if (route.path !== '!' && route.path[0] !== '/') {
|
||||||
|
console.error('路由规则必须以"/"开头')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
route.path = route.path.replace(/^[\/]+|[\/]+$|\s+/g, '')
|
||||||
|
|
||||||
|
this.#tables.set(route.path, this.#parseRule(route))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路由检测
|
||||||
|
#check(path) {
|
||||||
|
let { allowReload } = this.#options
|
||||||
|
let $view = window.__wkitd__.get('ROUTER_VIEW')
|
||||||
|
|
||||||
|
if (!$view || (!allowReload && path === this.#route.path)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// console.log('<><><><>')
|
||||||
|
|
||||||
|
for (let [k, route] of this.#tables) {
|
||||||
|
let args = path.match(route.regexp)
|
||||||
|
if (args) {
|
||||||
|
args.shift()
|
||||||
|
$view.current = route.name
|
||||||
|
this.#route.path = path
|
||||||
|
this.#route.name = route.name
|
||||||
|
this.#route.params = args
|
||||||
|
this.#route.query = {}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this.noMatch && this.noMatch(this.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.#hashchange()
|
||||||
|
}
|
||||||
|
|
||||||
|
getViews() {
|
||||||
|
return Array.from(this.#views)
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(callback) {
|
||||||
|
callback(prev, next, function () {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到路由
|
||||||
|
go(path) {
|
||||||
|
path = path.trim().replace(TRIM_REGEXP, '')
|
||||||
|
|
||||||
|
// 页面刷新时, 不主动添加空hash, 避免执行2次noMatch回调
|
||||||
|
if (!path && path === location.hash) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
location.hash = '!/' + path
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定路由事件
|
||||||
|
addRoute(routes) {
|
||||||
|
if (Array.isArray(routes)) {
|
||||||
|
routes.forEach(it => {
|
||||||
|
this.#add(it)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.#add(routes)
|
||||||
|
}
|
||||||
|
// 因为先初始化,才开始监听路由规则
|
||||||
|
// 所以会导致wondow load的时候, 规则还没生效, 而生效之后,load已经结束
|
||||||
|
// 所以这里需要手动再触发一次load
|
||||||
|
if (this[__ready__]) {
|
||||||
|
this.#hashchange()
|
||||||
|
} else {
|
||||||
|
fire(window, 'load')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return new Router()
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/08/10 10:10:06
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, html, raw } from 'wkit'
|
||||||
|
|
||||||
|
import createWebHashHistory from './hash-router.js'
|
||||||
|
import createWebHistory from './modern-router.js'
|
||||||
|
|
||||||
|
export { createWebHashHistory, createWebHistory }
|
||||||
|
|
||||||
|
class Router extends Component {
|
||||||
|
static props = {
|
||||||
|
keepAlive: false,
|
||||||
|
current: 'str!'
|
||||||
|
}
|
||||||
|
|
||||||
|
#views = []
|
||||||
|
|
||||||
|
created() {
|
||||||
|
window.__wkitd__.set('ROUTER_VIEW', this)
|
||||||
|
}
|
||||||
|
|
||||||
|
sync(views) {
|
||||||
|
this.#views = views
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.keepAlive) {
|
||||||
|
return html``
|
||||||
|
} else {
|
||||||
|
if (this.current) {
|
||||||
|
return raw(`<${this.current}></${this.current}>`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!customElements.get('router-view')) {
|
||||||
|
customElements.define('router-view', Router)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createRouter(
|
||||||
|
{ history = createWebHashHistory, routes = [] } = {},
|
||||||
|
options
|
||||||
|
) {
|
||||||
|
let $router = history(options)
|
||||||
|
|
||||||
|
window.__wkitd__.set('$router', $router)
|
||||||
|
Component.prototype.$router = $router
|
||||||
|
|
||||||
|
$router.addRoute(routes)
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
return $router
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRouter() {
|
||||||
|
return window.__wkitd__.get('$router')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCurrentPage() {
|
||||||
|
return getRouter().route
|
||||||
|
}
|
|
@ -0,0 +1,216 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @authors yutent (yutent@doui.cc)
|
||||||
|
* @date 2017-04-14 21:04:50
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import { bind } from 'wkit'
|
||||||
|
import { hideProp, targetIsThisWindow } from '../utils.js'
|
||||||
|
|
||||||
|
//hash前缀正则
|
||||||
|
const PREFIX_REGEXP = /^(#!|#)[\/]?/
|
||||||
|
const TRIM_REGEXP = /(^[/]+)|([/]+$)/g
|
||||||
|
const DEFAULT_OPTIONS = {
|
||||||
|
mode: 'hash', // hash | history
|
||||||
|
allowReload: true //连续点击同一个链接是否重新加载
|
||||||
|
}
|
||||||
|
const LINKS = []
|
||||||
|
const RULE_REGEXP =
|
||||||
|
/(:id)|(\{id\})|(\{id:([A-z\d\,\[\]\{\}\-\+\*\?\!:\^\$]*)\})/g
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
constructor(options) {
|
||||||
|
hideProp(this, 'table', [])
|
||||||
|
hideProp(this, 'last', '')
|
||||||
|
hideProp(this, 'path', '')
|
||||||
|
hideProp(this, 'pathArr', [])
|
||||||
|
hideProp(this, 'ready', false)
|
||||||
|
hideProp(this, 'noMatch', null)
|
||||||
|
hideProp(this, 'options', Object.assign({}, DEFAULT_OPTIONS, options))
|
||||||
|
this.__listen__()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 事件监听
|
||||||
|
__listen__() {
|
||||||
|
let { mode } = this.options
|
||||||
|
|
||||||
|
bind(window, 'load, popstate', ev => {
|
||||||
|
if (ev.type === 'load') {
|
||||||
|
if (this.ready) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.ready = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = mode === 'hash' ? location.hash : location.pathname
|
||||||
|
|
||||||
|
path = path.replace(PREFIX_REGEXP, '').trim()
|
||||||
|
path = path.replace(TRIM_REGEXP, '')
|
||||||
|
|
||||||
|
if (ev.type === 'load') {
|
||||||
|
this.go(path)
|
||||||
|
// hash模式要手动触发一下路由检测
|
||||||
|
if (mode === 'hash') {
|
||||||
|
this.__check__(path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 因为pushState不会触发popstate事件,
|
||||||
|
// 所以这里只在hash模式或有ev.state的情况下才会主动触发路由检测
|
||||||
|
if (mode === 'hash' || ev.state) {
|
||||||
|
this.__check__(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//劫持页面上所有点击事件,如果事件源来自链接或其内部,
|
||||||
|
//并且它不会跳出本页,并且以"#/"或"#!/"开头,那么触发go方法
|
||||||
|
bind(document, 'click', ev => {
|
||||||
|
let prevented =
|
||||||
|
'defaultPrevented' in ev
|
||||||
|
? ev.defaultPrevented
|
||||||
|
: ev.returnValue === false
|
||||||
|
|
||||||
|
if (prevented || ev.ctrlKey || ev.metaKey || ev.which === 2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let target = ev.target
|
||||||
|
while (target.nodeName !== 'A') {
|
||||||
|
target = target.parentNode
|
||||||
|
if (!target || target.tagName === 'BODY') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mode === 'history') {
|
||||||
|
if (targetIsThisWindow(target.target)) {
|
||||||
|
let href =
|
||||||
|
target.getAttribute('href') || target.getAttribute('xlink:href')
|
||||||
|
|
||||||
|
if (
|
||||||
|
!href ||
|
||||||
|
/^(http[s]?:|ftp:)?\/\//.test(href) ||
|
||||||
|
/^javascript:/.test(href)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// hash地址,只管修正前缀即可, 会触发popstate事件,所以这里只处理非hash的情况
|
||||||
|
if (!PREFIX_REGEXP.test(href)) {
|
||||||
|
// 非hash地址,则需要阻止默认事件
|
||||||
|
// 并主动触发跳转, 同时强制清除hash
|
||||||
|
ev.preventDefault()
|
||||||
|
this.go(href, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
__parseRule__(rule, opts) {
|
||||||
|
let re = rule.replace(RULE_REGEXP, function (m, p1, p2, p3, p4) {
|
||||||
|
let w = '([\\w.-]'
|
||||||
|
if (p1 || p2) {
|
||||||
|
return w + '+)'
|
||||||
|
} else {
|
||||||
|
if (!/^\{[\d\,]+\}$/.test(p4)) {
|
||||||
|
w = '('
|
||||||
|
}
|
||||||
|
return w + p4 + ')'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
re = re
|
||||||
|
.replace(/(([^\\])([\/]+))/g, '$2\\/')
|
||||||
|
.replace(/(([^\\])([\.]+))/g, '$2\\.')
|
||||||
|
.replace(/(([^\\])([\-]+))/g, '$2\\-')
|
||||||
|
.replace(/(\(.*)(\\[\-]+)(.*\))/g, '$1-$3')
|
||||||
|
re = '^' + re + '$'
|
||||||
|
opts.regexp = new RegExp(re)
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
__add__(rule, callback) {
|
||||||
|
// 特殊值"!", 则自动作非匹配回调处理
|
||||||
|
if (rule === '!') {
|
||||||
|
this.noMatch = callback
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (rule.charAt(0) !== '/') {
|
||||||
|
console.error('路由规则必须以"/"开头')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rule = rule.replace(/^[\/]+|[\/]+$|\s+/g, '')
|
||||||
|
let opts = { rule, callback }
|
||||||
|
|
||||||
|
Anot.Array.ensure(this.table, this.__parseRule__(rule, opts))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路由检测
|
||||||
|
__check__(path) {
|
||||||
|
let { allowReload } = this.options
|
||||||
|
if (!allowReload && path === this.last) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.last = this.path
|
||||||
|
this.path = path
|
||||||
|
this.pathArr = path.split('/')
|
||||||
|
LINKS.forEach(vm => {
|
||||||
|
if (vm.rule.test(this.path)) {
|
||||||
|
vm.active = true
|
||||||
|
} else {
|
||||||
|
vm.active = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
for (let i = 0, route; (route = this.table[i++]); ) {
|
||||||
|
let args = path.match(route.regexp)
|
||||||
|
if (args) {
|
||||||
|
args.shift()
|
||||||
|
return route.callback.apply(route, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.noMatch && this.noMatch(this.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到路由
|
||||||
|
go(path, forceCleanHash = false) {
|
||||||
|
path = path.trim().replace(TRIM_REGEXP, '')
|
||||||
|
let { mode } = this.options
|
||||||
|
|
||||||
|
if (mode === 'hash') {
|
||||||
|
// 页面刷新时, 不主动添加空hash, 避免执行2次noMatch回调
|
||||||
|
if (!path && path === location.hash) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
location.hash = '!/' + path
|
||||||
|
} else {
|
||||||
|
let hash = forceCleanHash ? '' : location.hash
|
||||||
|
let search = forceCleanHash ? '' : location.search
|
||||||
|
if (forceCleanHash) {
|
||||||
|
window.history.pushState({ path }, null, `/${path + search + hash}`)
|
||||||
|
} else {
|
||||||
|
window.history.replaceState({ path }, null, `/${path + search + hash}`)
|
||||||
|
}
|
||||||
|
// pushState不会触发popstate事件,所以要手动触发路由检测
|
||||||
|
this.__check__(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定路由事件
|
||||||
|
on(rule, callback) {
|
||||||
|
if (Array.isArray(rule)) {
|
||||||
|
rule.forEach(it => {
|
||||||
|
this.__add__(it, callback)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.__add__(rule, callback)
|
||||||
|
}
|
||||||
|
// 因为先初始化,才开始监听路由规则
|
||||||
|
// 所以会导致wondow load的时候, 规则还没生效, 而生效之后,load已经结束
|
||||||
|
// 所以这里需要手动再触发一次load
|
||||||
|
Anot.fireDom(window, 'load')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return new Router()
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/08/10 11:57:38
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component } from 'wkit'
|
||||||
|
|
||||||
|
export function createStore(obj = {}) {
|
||||||
|
window.__wkitd__.$store = obj
|
||||||
|
|
||||||
|
Component.prototype.$store = obj
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/08/10 10:07:51
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function noop() {}
|
||||||
|
|
||||||
|
export function hideProp(host, name, value) {
|
||||||
|
Object.defineProperty(host, name, {
|
||||||
|
value,
|
||||||
|
enumerable: false,
|
||||||
|
writable: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判定A标签的target属性是否指向自身
|
||||||
|
export function targetIsThisWindow(target) {
|
||||||
|
if (
|
||||||
|
!target ||
|
||||||
|
target === window.name ||
|
||||||
|
target === '_self' ||
|
||||||
|
(target === 'top' && window == window.top)
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
Loading…
Reference in New Issue