first commit

This commit is contained in:
2026-01-08 14:58:16 +08:00
commit 556e5d64aa
9575 changed files with 1621095 additions and 0 deletions
@@ -0,0 +1,400 @@
;(function umd(root, factory) {
if (typeof module === "object" && typeof exports === "object") module.exports = factory()
else if (typeof define === "function" && define.amd) define([], factory)
else root.httpVueLoader = factory()
})(this, function factory() {
"use strict"
var scopeIndex = 0
StyleContext.prototype = {
withBase: function (callback) {
var tmpBaseElt
if (this.component.baseURI) {
// firefox and chrome need the <base> to be set while inserting or modifying <style> in a document.
tmpBaseElt = document.createElement("base")
tmpBaseElt.href = this.component.baseURI
var headElt = this.component.getHead()
headElt.insertBefore(tmpBaseElt, headElt.firstChild)
}
callback.call(this)
if (tmpBaseElt) this.component.getHead().removeChild(tmpBaseElt)
},
scopeStyles: function (styleElt, scopeName) {
function process() {
var sheet = styleElt.sheet
var rules = sheet.cssRules
for (var i = 0; i < rules.length; ++i) {
var rule = rules[i]
if (rule.type !== 1) continue
var scopedSelectors = []
rule.selectorText.split(/\s*,\s*/).forEach(function (sel) {
scopedSelectors.push(scopeName + " " + sel)
var segments = sel.match(/([^ :]+)(.+)?/)
scopedSelectors.push(segments[1] + scopeName + (segments[2] || ""))
})
var scopedRule = scopedSelectors.join(",") + rule.cssText.substr(rule.selectorText.length)
sheet.deleteRule(i)
sheet.insertRule(scopedRule, i)
}
}
try {
// firefox may fail sheet.cssRules with InvalidAccessError
process()
} catch (ex) {
if (ex instanceof DOMException && ex.code === DOMException.INVALID_ACCESS_ERR) {
styleElt.sheet.disabled = true
styleElt.addEventListener("load", function onStyleLoaded() {
styleElt.removeEventListener("load", onStyleLoaded)
// firefox need this timeout otherwise we have to use document.importNode(style, true)
setTimeout(function () {
process()
styleElt.sheet.disabled = false
})
})
return
}
throw ex
}
},
compile: function () {
var hasTemplate = this.template !== null
var scoped = this.elt.hasAttribute("scoped")
if (scoped) {
// no template, no scopable style needed
if (!hasTemplate) return
// firefox does not tolerate this attribute
this.elt.removeAttribute("scoped")
}
this.withBase(function () {
this.component.getHead().appendChild(this.elt)
})
if (scoped) this.scopeStyles(this.elt, "[" + this.component.getScopeId() + "]")
return Promise.resolve()
},
getContent: function () {
return this.elt.textContent
},
setContent: function (content) {
this.withBase(function () {
this.elt.textContent = content
})
}
}
function StyleContext(component, elt) {
this.component = component
this.elt = elt
}
ScriptContext.prototype = {
getContent: function () {
return this.elt.textContent
},
setContent: function (content) {
this.elt.textContent = content
},
compile: function (module) {
var childModuleRequire = function (childURL) {
return httpVueLoader.require(resolveURL(this.component.baseURI, childURL))
}.bind(this)
var childLoader = function (childURL, childName) {
return httpVueLoader(resolveURL(this.component.baseURI, childURL), childName)
}.bind(this)
try {
Function("exports", "require", "httpVueLoader", "module", this.getContent()).call(
this.module.exports,
this.module.exports,
childModuleRequire,
childLoader,
this.module
)
} catch (ex) {
if (!("lineNumber" in ex)) {
return Promise.reject(ex)
}
var vueFileData = responseText.replace(/\r?\n/g, "\n")
var lineNumber = vueFileData.substr(0, vueFileData.indexOf(script)).split("\n").length + ex.lineNumber - 1
throw new ex.constructor(ex.message, url, lineNumber)
}
return Promise.resolve(this.module.exports)
.then(httpVueLoader.scriptExportsHandler.bind(this))
.then(
function (exports) {
this.module.exports = exports
}.bind(this)
)
}
}
function ScriptContext(component, elt) {
this.component = component
this.elt = elt
this.module = { exports: {} }
}
TemplateContext.prototype = {
getContent: function () {
return this.elt.innerHTML
},
setContent: function (content) {
this.elt.innerHTML = content
},
getRootElt: function () {
var tplElt = this.elt.content || this.elt
if ("firstElementChild" in tplElt) return tplElt.firstElementChild
for (tplElt = tplElt.firstChild; tplElt !== null; tplElt = tplElt.nextSibling) if (tplElt.nodeType === Node.ELEMENT_NODE) return tplElt
return null
},
compile: function () {
return Promise.resolve()
}
}
function TemplateContext(component, elt) {
this.component = component
this.elt = elt
}
Component.prototype = {
getHead: function () {
return document.head || document.getElementsByTagName("head")[0]
},
getScopeId: function () {
if (this._scopeId === "") {
this._scopeId = "data-s-" + (scopeIndex++).toString(36)
this.template.getRootElt().setAttribute(this._scopeId, "")
}
return this._scopeId
},
load: function (componentURL) {
return httpVueLoader.httpRequest(componentURL).then(
function (responseText) {
this.baseURI = componentURL.substr(0, componentURL.lastIndexOf("/") + 1)
var doc = document.implementation.createHTMLDocument("")
// IE requires the <base> to come with <style>
doc.body.innerHTML = (this.baseURI ? '<base href="' + this.baseURI + '">' : "") + responseText
for (var it = doc.body.firstChild; it; it = it.nextSibling) {
switch (it.nodeName) {
case "TEMPLATE":
this.template = new TemplateContext(this, it)
break
case "SCRIPT":
this.script = new ScriptContext(this, it)
break
case "STYLE":
this.styles.push(new StyleContext(this, it))
break
}
}
return this
}.bind(this)
)
},
_normalizeSection: function (eltCx) {
var p
if (eltCx === null || !eltCx.elt.hasAttribute("src")) {
p = Promise.resolve(null)
} else {
p = httpVueLoader.httpRequest(eltCx.elt.getAttribute("src")).then(function (content) {
eltCx.elt.removeAttribute("src")
return content
})
}
return p
.then(
function (content) {
if (eltCx !== null && eltCx.elt.hasAttribute("lang")) {
var lang = eltCx.elt.getAttribute("lang")
eltCx.elt.removeAttribute("lang")
return httpVueLoader.langProcessor[lang.toLowerCase()].call(this, content === null ? eltCx.getContent() : content)
}
return content
}.bind(this)
)
.then(function (content) {
if (content !== null) eltCx.setContent(content)
})
},
normalize: function () {
return Promise.all(
Array.prototype.concat(
this._normalizeSection(this.template),
this._normalizeSection(this.script),
this.styles.map(this._normalizeSection)
)
).then(
function () {
return this
}.bind(this)
)
},
compile: function () {
return Promise.all(
Array.prototype.concat(
this.template && this.template.compile(),
this.script && this.script.compile(),
this.styles.map(function (style) {
return style.compile()
})
)
).then(
function () {
return this
}.bind(this)
)
}
}
function Component(name) {
this.name = name
this.template = null
this.script = null
this.styles = []
this._scopeId = ""
}
function identity(value) {
return value
}
function parseComponentURL(url) {
var comp = url.match(/(.*?)([^/]+?)\/?(\.vue)?(\?.*|#.*|$)/)
return {
name: comp[2],
url: comp[1] + comp[2] + (comp[3] === undefined ? "/index.vue" : comp[3]) + comp[4]
}
}
function resolveURL(baseURL, url) {
if (url.substr(0, 2) === "./" || url.substr(0, 3) === "../") {
return baseURL + url
}
return url
}
httpVueLoader.load = function (url, name) {
return function () {
return new Component(name)
.load(url)
.then(function (component) {
return component.normalize()
})
.then(function (component) {
return component.compile()
})
.then(function (component) {
var exports = component.script !== null ? component.script.module.exports : {}
if (component.template !== null) exports.template = component.template.getContent()
if (exports.name === undefined) if (component.name !== undefined) exports.name = component.name
exports._baseURI = component.baseURI
return exports
})
}
}
httpVueLoader.register = function (Vue, url) {
var comp = parseComponentURL(url)
Vue.component(comp.name, httpVueLoader.load(comp.url))
}
httpVueLoader.install = function (Vue) {
Vue.mixin({
beforeCreate: function () {
var components = this.$options.components
for (var componentName in components) {
if (typeof components[componentName] === "string" && components[componentName].substr(0, 4) === "url:") {
var comp = parseComponentURL(components[componentName].substr(4))
var componentURL = "_baseURI" in this.$options ? resolveURL(this.$options._baseURI, comp.url) : comp.url
if (isNaN(componentName)) components[componentName] = httpVueLoader.load(componentURL, componentName)
else components[componentName] = Vue.component(comp.name, httpVueLoader.load(componentURL, comp.name))
}
}
}
})
}
httpVueLoader.require = function (moduleName) {
return window[moduleName]
}
httpVueLoader.httpRequest = function (url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.responseType = "text"
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) resolve(xhr.responseText)
else reject(xhr.status)
}
}
xhr.send(null)
})
}
httpVueLoader.langProcessor = {
html: identity,
js: identity,
css: identity
}
httpVueLoader.scriptExportsHandler = identity
function httpVueLoader(url, name) {
var comp = parseComponentURL(url)
return httpVueLoader.load(comp.url, name)
}
return httpVueLoader
})