mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Add VueBuilder and vue files
This commit is contained in:
parent
7dcecc88d3
commit
237f3d591b
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -29,6 +29,7 @@ namespace BilibiliEvolved.Build
|
||||
.BuildClient()
|
||||
.BuildPreview()
|
||||
.BuildMaster()
|
||||
.BuildVue()
|
||||
.BuildTypeScripts()
|
||||
.BuildSass()
|
||||
.BuildResources()
|
||||
|
||||
@ -31,7 +31,11 @@ namespace BilibiliEvolved.Build
|
||||
});
|
||||
Console.Write(tsc.Run().Trim());
|
||||
Parallel.ForEach(changedFiles.Select(f => ".ts-output/" + f.Replace(".ts", ".js").Replace($"src{Path.DirectorySeparatorChar}", "")), file => {
|
||||
var min = uglifyJs.Minify(File.ReadAllText(file));
|
||||
var text = RegexReplacer.Replace(File.ReadAllText(file), @"import\(\(\(\)\s*=>\s*(.*)\)\(\)\)", match => {
|
||||
Console.WriteLine($"import({match.Groups[1].Value})");
|
||||
return $"import({match.Groups[1].Value})";
|
||||
});
|
||||
var min = uglifyJs.Minify(text);
|
||||
var minFile = ResourceMinifier.GetMinimizedFileName(file);
|
||||
File.WriteAllText(minFile, min);
|
||||
WriteHint($"\t=> {minFile}");
|
||||
|
||||
104
builder/dotnet/VueBuilder.cs
Normal file
104
builder/dotnet/VueBuilder.cs
Normal file
@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BilibiliEvolved.Build
|
||||
{
|
||||
sealed class VueBuildException : Exception
|
||||
{
|
||||
public VueBuildException(string message) : base(message) {}
|
||||
}
|
||||
partial class ProjectBuilder
|
||||
{
|
||||
public ProjectBuilder BuildVue()
|
||||
{
|
||||
var files = ResourceMinifier.GetFiles(file =>
|
||||
file.FullName.Contains(@"src\") &&
|
||||
file.Extension == ".vue"
|
||||
);
|
||||
using (var cache = new BuildCache())
|
||||
{
|
||||
var changedFiles = files.Where(file => !cache.Contains(file)).ToArray();
|
||||
if (changedFiles.Any())
|
||||
{
|
||||
Parallel.ForEach(changedFiles, file =>
|
||||
{
|
||||
cache.AddCache(file);
|
||||
WriteInfo($"Vue build: {file}");
|
||||
var source = File.ReadAllText(file);
|
||||
var compiledText = new StringBuilder("");
|
||||
{
|
||||
var regex = @"<template\s*(lang=""(.+)"")?\s*>([^\0]*)</template>";
|
||||
var match = new Regex(regex).Match(source);
|
||||
if (match is null)
|
||||
{
|
||||
throw new VueBuildException($"Missing <template> in {file}.");
|
||||
}
|
||||
if (match.Groups.Count >= 4 && match.Groups[2].Value.ToLowerInvariant() != "html")
|
||||
{
|
||||
throw new VueBuildException($"{file}: Unsupported template lang: {match.Groups[2].Value.ToLowerInvariant()}");
|
||||
}
|
||||
var index = match.Groups.Count >= 4 ? 4 : 1;
|
||||
compiledText.AppendLine($"const template = /*html*/`{match.Groups[index].Value}`");
|
||||
}
|
||||
{
|
||||
var regex = @"<script\s*(lang=""(.+)"")?\s*>([^\0]*)</script>";
|
||||
var match = new Regex(regex).Match(source);
|
||||
if (match is null)
|
||||
{
|
||||
throw new VueBuildException($"Missing <script> in {file}.");
|
||||
}
|
||||
var contentIndex = match.Groups.Count >= 4 ? 4 : 1;
|
||||
var content = match.Groups[contentIndex].Value;
|
||||
var lang = match.Groups.Count >= 4 ? match.Groups[2].Value.ToLowerInvariant() : "js";
|
||||
if (lang == "js" || lang == "javascript")
|
||||
{
|
||||
var jsc = new UglifyJs();
|
||||
var result = jsc.Run(content);
|
||||
|
||||
}
|
||||
else if (lang == "ts" || lang == "typescript")
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new VueBuildException($"{file}: Unsupported script lang: {lang}");
|
||||
}
|
||||
}
|
||||
{
|
||||
var regex = @"<style\s*(lang=""(.+)"")?\s*>([^\0]*)</style>";
|
||||
var match = new Regex(regex).Match(source);
|
||||
if (match != null)
|
||||
{
|
||||
var contentIndex = match.Groups.Count >= 4 ? 4 : 1;
|
||||
var content = match.Groups[contentIndex].Value;
|
||||
var lang = match.Groups.Count >= 4 ? match.Groups[2].Value.ToLowerInvariant() : "css";
|
||||
if (lang == "css")
|
||||
{
|
||||
|
||||
}
|
||||
else if (lang == "scss")
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new VueBuildException($"{file}: Unsupported style lang: {lang}");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
cache.SaveCache();
|
||||
}
|
||||
WriteSuccess("Vue build complete.");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
2
min/download-video.min.css
vendored
2
min/download-video.min.css
vendored
File diff suppressed because one or more lines are too long
12
min/download-video.min.js
vendored
12
min/download-video.min.js
vendored
File diff suppressed because one or more lines are too long
@ -114,54 +114,6 @@ body.dark .download-video {
|
||||
padding-top: 12px;
|
||||
font-size: 10pt;
|
||||
}
|
||||
.v-dropdown {
|
||||
position: relative;
|
||||
background-color: #8884;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-width: 100px;
|
||||
}
|
||||
.v-dropdown .dropdown-menu {
|
||||
transform-origin: top;
|
||||
transform: scaleY(0) translateX(-50%);
|
||||
position: absolute;
|
||||
top: calc(100% + 2px);
|
||||
left: 50%;
|
||||
background-color: var(--download-video-background);
|
||||
z-index: 1;
|
||||
transition: .2s cubic-bezier(0.6, -0.28, 0.74, 0.05);
|
||||
box-shadow: rgba(0,0,0,0.2) 0 4px 8px 0px;
|
||||
}
|
||||
.v-dropdown .dropdown-menu.opened {
|
||||
transform: scaleY(1) translateX(-50%);
|
||||
transition-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
||||
}
|
||||
.v-dropdown .dropdown-menu li {
|
||||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
min-width: 80px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
color: var(--download-video-foreground);
|
||||
background-color: transparent;
|
||||
}
|
||||
.v-dropdown .dropdown-menu li:hover {
|
||||
background-color: rgba(0,0,0,0.16);
|
||||
}
|
||||
.v-dropdown .mdi-chevron-down {
|
||||
font-size: 16pt;
|
||||
line-height: 1;
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
.v-dropdown .dropdown-menu.opened ~ .mdi-chevron-down {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.v-dropdown .selected {
|
||||
user-select: none;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
.download-video .tabs {
|
||||
display: flex;
|
||||
padding-top: 12px;
|
||||
|
||||
@ -496,35 +496,8 @@ async function loadWidget() {
|
||||
}, { once: true })
|
||||
}
|
||||
async function loadPanel() {
|
||||
Vue.component('v-dropdown', {
|
||||
template: /*html*/`
|
||||
<div class="v-dropdown" v-on:click="toggleDropdown()">
|
||||
<span class="selected">{{value}}</span>
|
||||
<ul class="dropdown-menu" v-bind:class="{opened: dropdownOpen}">
|
||||
<li v-for="item in items" v-bind:key="item" v-bind:data-value="item" v-on:click="select(item)">{{item}}</li>
|
||||
</ul>
|
||||
<i class="mdi mdi-chevron-down"></i>
|
||||
</div>
|
||||
`,
|
||||
props: [
|
||||
'items',
|
||||
'value'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
dropdownOpen: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleDropdown() {
|
||||
this.dropdownOpen = !this.dropdownOpen
|
||||
},
|
||||
select(item: string) {
|
||||
this.$emit('update:value', item)
|
||||
this.$emit('change', item)
|
||||
},
|
||||
},
|
||||
})
|
||||
const VueDropDown = await import((() => './v-dropdown.vue')())
|
||||
Vue.component('v-dropdown', VueDropDown)
|
||||
Vue.component('v-checkbox', {
|
||||
template: /*html*/`
|
||||
<div class="v-checkbox" v-on:click="toggleCheck()" v-bind:class="{checked: checked}">
|
||||
|
||||
79
src/video/download-video/v-dropdown.vue
Normal file
79
src/video/download-video/v-dropdown.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="v-dropdown" @click="toggleDropdown()">
|
||||
<span class="selected">{{ value }}</span>
|
||||
<ul class="dropdown-menu" :class="{ opened: dropdownOpen }">
|
||||
<li v-for="item in items" :key="item" :data-value="item" @click="select(item)">{{ item }}</li>
|
||||
</ul>
|
||||
<i class="mdi mdi-chevron-down"></i>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
props: ['items', 'value'],
|
||||
data() {
|
||||
return {
|
||||
dropdownOpen: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleDropdown() {
|
||||
this.dropdownOpen = !this.dropdownOpen
|
||||
},
|
||||
select(item: string) {
|
||||
this.$emit('update:value', item)
|
||||
this.$emit('change', item)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.v-dropdown {
|
||||
position: relative;
|
||||
background-color: #8884;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-width: 100px;
|
||||
|
||||
.dropdown-menu {
|
||||
transform-origin: top;
|
||||
transform: scaleY(0) translateX(-50%);
|
||||
position: absolute;
|
||||
top: calc(100% + 2px);
|
||||
left: 50%;
|
||||
background-color: var(--download-video-background);
|
||||
z-index: 1;
|
||||
transition: 0.2s cubic-bezier(0.6, -0.28, 0.74, 0.05);
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 4px 8px 0px;
|
||||
&.opened {
|
||||
transform: scaleY(1) translateX(-50%);
|
||||
transition-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
||||
}
|
||||
li {
|
||||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
min-width: 80px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
color: var(--download-video-foreground);
|
||||
background-color: transparent;
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
}
|
||||
}
|
||||
.mdi-chevron-down {
|
||||
font-size: 16pt;
|
||||
line-height: 1;
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
.dropdown-menu.opened ~ .mdi-chevron-down {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.selected {
|
||||
user-select: none;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user