From 07eb44c0372e7ece42c582500ac5853f4c98a0aa Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Sat, 10 Oct 2026 16:47:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=BC=96=E8=BE=91=E6=B8=B2=E6=9F=93):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B7=B3=E8=BD=AC=E9=81=97=E6=BC=8F=E4=B8=8E?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E9=87=8D=E5=A4=8D=E8=AF=BB=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/webui/wasm.go | 26 ++++++++++++++++++++------ ofdgo_doc.go | 32 +++++++++++++++++++++++++++++++- ofdgo_editor_outline.go | 12 +++++++----- ofdgo_image_resource.go | 2 +- ofdgo_renderer_pdf_canvas.go | 2 +- 5 files changed, 60 insertions(+), 14 deletions(-) diff --git a/internal/webui/wasm.go b/internal/webui/wasm.go index ad8caab..bfa1f80 100644 --- a/internal/webui/wasm.go +++ b/internal/webui/wasm.go @@ -960,7 +960,7 @@ func linkResults(source []ofdgo.PageLink) ([]any, error) { } } if dest := link.Dest; dest != nil { - item["dest"] = map[string]any{"type": dest.Type, "pageID": dest.PageID, "left": dest.Left, "top": dest.Top, + item["dest"] = map[string]any{"type": dest.Type, "pageID": resolvedPageID(dest.PageID), "left": dest.Left, "top": dest.Top, "right": dest.Right, "bottom": dest.Bottom, "zoom": dest.Zoom, "omitLeft": dest.OmitLeft, "omitTop": dest.OmitTop, "omitZoom": dest.OmitZoom} } @@ -969,6 +969,18 @@ func linkResults(source []ofdgo.PageLink) ([]any, error) { return links, nil } +// resolvedPageID 将跳转目标转换为界面页面列表中的标识,未找到时保留原值 +// 入参: id 目标页面标识 +// 返回: string 页面列表标识或原值 +func resolvedPageID(id string) string { + if currentSession != nil { + if index := currentSession.doc.PageIndex(id); index >= 0 { + return currentSession.doc.Pages.Page[index].ID + } + } + return id +} + // pageTextString 提取OFD页面原文 // 入参: args 页面索引 // 返回: any 页面原文, error 错误信息 @@ -1513,11 +1525,8 @@ func readAnnotation(args []js.Value) (any, error) { info["linkKind"], info["linkURI"], info["linkBase"] = "uri", link.URI.URI, link.URI.Base info["linkTarget"] = link.URI.Target } else if err == nil && link.Goto != nil && link.Goto.Dest != nil { - for i, page := range currentSession.doc.Pages.Page { - if page.ID == link.Goto.Dest.PageID { - info["linkKind"], info["linkPage"] = "page", i+1 - break - } + if index := currentSession.doc.PageIndex(link.Goto.Dest.PageID); index >= 0 { + info["linkKind"], info["linkPage"] = "page", index+1 } } } @@ -1815,6 +1824,11 @@ func editorAppearance(item map[string]any, object ofdgo.GraphicObject, paint boo for _, action := range object.Actions() { if action.Event == "CLICK" && (action.URI != nil || action.Goto != nil) { links++ + if action.Goto != nil && action.Goto.Dest != nil { + gotoAction, dest := *action.Goto, *action.Goto.Dest + dest.PageID = resolvedPageID(dest.PageID) + gotoAction.Dest, action.Goto = &dest, &gotoAction + } if data, err := json.Marshal(action); err == nil { item["link"] = string(data) } diff --git a/ofdgo_doc.go b/ofdgo_doc.go index 2243a04..6050dcb 100644 --- a/ofdgo_doc.go +++ b/ofdgo_doc.go @@ -201,6 +201,36 @@ type print struct { Copies *int `xml:"Copies,attr"` } +// PageIndex 按标识查找页面,优先匹配原文和标准十进制写法,等价编号有歧义时不匹配 +// 入参: id 页面标识 +// 返回: int 从0开始的页面索引,未找到时为-1 +func (doc *Document) PageIndex(id string) int { + if doc == nil { + return -1 + } + index, key := -1, editorResourceID(id) + for i, page := range doc.Pages.Page { + if page.ID == id { + return i + } + if key != "" && page.ID == key { + index = i + } + } + if index >= 0 || key == "" { + return index + } + for i, page := range doc.Pages.Page { + if editorResourceID(page.ID) == key { + if index >= 0 { + return -1 + } + index = i + } + } + return index +} + // OutlineInfos 获取目录层级和目标页码 // 返回: []OutlineInfo 目录节点信息 func (doc *Document) OutlineInfos() []OutlineInfo { @@ -342,7 +372,7 @@ func outlineInfos(outlines []OutlineElem, bookmarks map[string]Dest, pages map[s for _, action := range outline.Actions { if action.Goto != nil { if dest := gotoDest(action.Goto, bookmarks); dest != nil { - info.Page = pages[dest.PageID] + info.Page, _ = resourceValue(pages, dest.PageID) if info.Page != 0 { break } diff --git a/ofdgo_editor_outline.go b/ofdgo_editor_outline.go index 39303df..97c1a8f 100644 --- a/ofdgo_editor_outline.go +++ b/ofdgo_editor_outline.go @@ -462,9 +462,9 @@ func (e *Editor) withOutlines(data []byte) ([]byte, error) { if err != nil { return nil, err } - valid := make(map[string]bool, len(e.pages)) - for _, page := range e.pages { - valid[page.ID] = true + valid := make(map[string]int, len(e.pages)) + for i, page := range e.pages { + valid[page.ID] = i } var removals []editorXMLPatch var walk func(*editorXML) @@ -475,8 +475,10 @@ func (e *Editor) withOutlines(data []byte) ([]byte, error) { continue } if target := action.child("Goto"); target != nil { - if dest := target.child("Dest"); dest != nil && !valid[dest.attr("PageID")] { - removals = append(removals, editorXMLPatch{action.start, action.end, nil}) + if dest := target.child("Dest"); dest != nil { + if _, ok := resourceValue(valid, dest.attr("PageID")); !ok { + removals = append(removals, editorXMLPatch{action.start, action.end, nil}) + } } } } diff --git a/ofdgo_image_resource.go b/ofdgo_image_resource.go index 4da8f71..b880800 100644 --- a/ofdgo_image_resource.go +++ b/ofdgo_image_resource.go @@ -110,7 +110,7 @@ func (r *Renderer) imageObjectResource(object ImageObject) (image.Image, error) return img, err } img, err := read(object.ResourceID) - if err == nil || object.Substitution == "" || object.Substitution == object.ResourceID { + if err == nil || object.Substitution == "" || sameResourceID(object.Substitution, object.ResourceID) { return img, err } if r.pageContext != nil && r.pageContext.Err() != nil { diff --git a/ofdgo_renderer_pdf_canvas.go b/ofdgo_renderer_pdf_canvas.go index 4438396..8a8aa91 100644 --- a/ofdgo_renderer_pdf_canvas.go +++ b/ofdgo_renderer_pdf_canvas.go @@ -234,7 +234,7 @@ func (n *pdfNavigation) actionTarget(action Action, page int, source actionSourc if dest == nil { return nil, nil } - target, ok := pageIndex[dest.PageID] + target, ok := resourceValue(pageIndex, dest.PageID) if !ok { return nil, nil }