mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 16:59:27 +08:00
1 parent
91e5b57e24
commit
e91c30ca3c
5 files changed
+77
-36
No files matched your search
+37
-7
@@ -1215,6 +1215,7 @@ button:not(:disabled):hover {
|
||||
|
||||
.info-custom-row input,
|
||||
.gradient-stop-row input,
|
||||
.structure-attribute > input,
|
||||
.form-row input[type="text"],
|
||||
.form-row input[type="password"],
|
||||
.form-row input[type="number"],
|
||||
@@ -3049,26 +3050,55 @@ audio.page-media {
|
||||
text-align-last: justify;
|
||||
}
|
||||
|
||||
.structure-dialog .panel-row {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.structure-dialog .panel-row > span {
|
||||
width: 4em;
|
||||
text-align-last: justify;
|
||||
}
|
||||
|
||||
.structure-dialog .form-actions {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.structure-edit-list {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
gap: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.structure-edit-list:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.structure-attribute {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 28px;
|
||||
gap: 6px;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) var(--control-height);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.structure-attribute .structure-attribute-value {
|
||||
grid-column: 1 / 3;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.structure-attribute > button {
|
||||
grid-column: 3;
|
||||
grid-row: 1 / 3;
|
||||
align-self: center;
|
||||
grid-column: -2;
|
||||
grid-row: 1;
|
||||
width: var(--control-height);
|
||||
height: var(--control-height);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.structure-attribute {
|
||||
grid-template-columns: minmax(0, 1fr) var(--control-height);
|
||||
}
|
||||
|
||||
.structure-attribute > input[name="namespace"] {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.structure-reference + .structure-reference {
|
||||
|
||||
@@ -8342,6 +8342,7 @@ function addStructureAttribute(attribute = {}) {
|
||||
row.className = "structure-attribute";
|
||||
for (const [name, label] of [["name", "属性名称"], ["namespace", "命名空间"], ["value", "属性内容"]]) {
|
||||
const input = document.createElement("input");
|
||||
input.type = "text";
|
||||
input.name = name;
|
||||
input.value = attribute[name] || "";
|
||||
input.placeholder = label;
|
||||
@@ -8365,6 +8366,7 @@ function addStructureReference(reference = {}) {
|
||||
const row = document.createElement("div");
|
||||
row.className = "structure-reference";
|
||||
const page = document.createElement("select"), object = document.createElement("select"), ids = document.createElement("input");
|
||||
ids.type = "text";
|
||||
page.name = "page";
|
||||
ids.name = "ids";
|
||||
ids.value = (reference.objectIds || []).join(",");
|
||||
|
||||
+1
-21
@@ -320,29 +320,9 @@ func (e *Editor) sourceMaxID(progress editorProgress) (int, error) {
|
||||
// 返回: int 最大标识, error 错误信息
|
||||
func editorXMLMaxID(input io.Reader) (int, error) {
|
||||
buffer := bufio.NewReader(input)
|
||||
header, err := buffer.Peek(3)
|
||||
if err != nil && err != io.EOF {
|
||||
if found, err := editorXMLPrefix(buffer); err != nil || !found {
|
||||
return 0, err
|
||||
}
|
||||
if bytes.Equal(header, []byte{0xef, 0xbb, 0xbf}) {
|
||||
buffer.Discard(3)
|
||||
}
|
||||
for {
|
||||
header, err := buffer.Peek(1)
|
||||
if err == io.EOF {
|
||||
return 0, nil
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !strings.ContainsRune(" \t\r\n", rune(header[0])) {
|
||||
if header[0] != '<' {
|
||||
return 0, nil
|
||||
}
|
||||
break
|
||||
}
|
||||
buffer.Discard(1)
|
||||
}
|
||||
decoder := xml.NewDecoder(buffer)
|
||||
maximum, started := 0, false
|
||||
for {
|
||||
|
||||
@@ -16,7 +16,6 @@ package ofdgo
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
@@ -317,15 +316,11 @@ func (e *Editor) compactResourceReferences(parts map[string][]byte, reader *Read
|
||||
// 返回: bool 是否资源索引, bool 是否可完整判断引用
|
||||
func (r *editorResourceRefs) scan(input io.Reader, name string) (bool, bool) {
|
||||
buffer := bufio.NewReader(input)
|
||||
header, err := buffer.Peek(512)
|
||||
if err != nil && err != io.EOF {
|
||||
found, err := editorXMLPrefix(buffer)
|
||||
if err != nil {
|
||||
return false, false
|
||||
}
|
||||
header = bytes.TrimSpace(bytes.TrimPrefix(header, []byte{0xef, 0xbb, 0xbf}))
|
||||
if len(header) == 0 {
|
||||
return false, err == io.EOF && !strings.EqualFold(path.Ext(name), ".xml")
|
||||
}
|
||||
if header[0] != '<' {
|
||||
if !found {
|
||||
return false, !strings.EqualFold(path.Ext(name), ".xml")
|
||||
}
|
||||
decoder := xml.NewDecoder(buffer)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package ofdgo
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
@@ -39,6 +40,39 @@ type editorXMLPatch struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
// editorXMLPrefix 跳过UTF-8字节序标记和XML空白,探测后保留首个内容字节
|
||||
// 入参: input 带缓冲的输入流,读取错误及取消信号由底层传递
|
||||
// 返回: bool 是否以XML标记起始, error 读取错误
|
||||
func editorXMLPrefix(input *bufio.Reader) (bool, error) {
|
||||
header, err := input.Peek(3)
|
||||
if err != nil && err != io.EOF {
|
||||
return false, err
|
||||
}
|
||||
if bytes.Equal(header, []byte{0xef, 0xbb, 0xbf}) {
|
||||
input.Discard(3)
|
||||
}
|
||||
for {
|
||||
if _, err := input.Peek(1); err != nil {
|
||||
if err == io.EOF {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
chunk, _ := input.Peek(input.Buffered())
|
||||
count := 0
|
||||
for count < len(chunk) {
|
||||
switch chunk[count] {
|
||||
case ' ', '\t', '\r', '\n':
|
||||
count++
|
||||
default:
|
||||
input.Discard(count)
|
||||
return chunk[count] == '<', nil
|
||||
}
|
||||
}
|
||||
input.Discard(count)
|
||||
}
|
||||
}
|
||||
|
||||
// parseEditorXML 解析节点位置,保留命名空间、注释和原始格式
|
||||
// 入参: data XML原文
|
||||
// 返回: *editorXML 根节点, error 错误信息
|
||||
|
||||
Reference in new issue
Block a user