From 4a17acce11ed048e7a090b3294ac5bd39be32473 Mon Sep 17 00:00:00 2001 From: Harvey Kandola Date: Mon, 24 Oct 2016 19:20:29 -0700 Subject: [PATCH] wip --- .../edit-tools.js} | 37 +++-- app/app/components/folder/folder-toolbar.js | 132 +++++++++--------- .../components/section/wysiwyg/type-editor.js | 38 ++--- app/app/components/ui/ui-checkbox.js | 16 +++ app/app/services/link.js | 18 +++ app/app/styles/app.scss | 4 +- app/app/styles/base.scss | 2 +- app/app/styles/view/content-linker.scss | 16 --- app/app/styles/view/document/edit-tools.scss | 29 ++++ app/app/styles/widget/widget-checkbox.scss | 21 +++ app/app/styles/widget/widget.scss | 51 +++---- .../components/document/edit-tools.hbs | 44 ++++++ .../components/folder/folders-list.hbs | 11 +- .../components/link/content-linker.hbs | 21 --- .../section/wysiwyg/type-editor.hbs | 7 +- .../templates/components/ui/ui-checkbox.hbs | 8 ++ core/api/endpoint/link_endpoint.go | 11 +- core/api/entity/objects.go | 32 +++-- core/api/request/link.go | 27 ++++ 19 files changed, 322 insertions(+), 203 deletions(-) rename app/app/components/{link/content-linker.js => document/edit-tools.js} (64%) create mode 100644 app/app/components/ui/ui-checkbox.js delete mode 100644 app/app/styles/view/content-linker.scss create mode 100644 app/app/styles/view/document/edit-tools.scss create mode 100644 app/app/styles/widget/widget-checkbox.scss create mode 100644 app/app/templates/components/document/edit-tools.hbs delete mode 100644 app/app/templates/components/link/content-linker.hbs create mode 100644 app/app/templates/components/ui/ui-checkbox.hbs diff --git a/app/app/components/link/content-linker.js b/app/app/components/document/edit-tools.js similarity index 64% rename from app/app/components/link/content-linker.js rename to app/app/components/document/edit-tools.js index 59ba00f5..7d4794ca 100644 --- a/app/app/components/link/content-linker.js +++ b/app/app/components/document/edit-tools.js @@ -10,16 +10,18 @@ // https://documize.com import Ember from 'ember'; +import TooltipMixin from '../../mixins/tooltip'; const { inject: { service } } = Ember; -export default Ember.Component.extend({ +export default Ember.Component.extend(TooltipMixin, { link: service(), hasSections: false, hasAttachments: false, linkName: '', + keywords: '', selection: null, init() { @@ -36,24 +38,37 @@ export default Ember.Component.extend({ }); }, - didReceiveAttrs() {}, + didRender() { + this.addTooltip(document.getElementById("content-linker-button")); + }, - didInsertElement() {}, - - willDestroyElement() {}, + willDestroyElement() { + this.destroyTooltips(); + }, actions: { + setSelection(i) { + this.set('selection', i); + + let candidates = this.get('candidates'); + + candidates.pages.forEach(c => { + Ember.set(c, 'selected', c.id === i.id); + }); + + candidates.attachments.forEach(c => { + Ember.set(c, 'selected', c.id === i.id); + }); + }, + onInsertLink() { let selection = this.get('selection'); - let linkName = this.get('linkName'); - if (linkName.length) { - selection.title = linkName; + if (is.null(selection)) { + return; } - if (is.not.null(selection)) { - this.get('onInsertLink')(selection); - } + return this.get('onInsertLink')(selection); } } }); diff --git a/app/app/components/folder/folder-toolbar.js b/app/app/components/folder/folder-toolbar.js index 466087cf..5f74b5bb 100644 --- a/app/app/components/folder/folder-toolbar.js +++ b/app/app/components/folder/folder-toolbar.js @@ -14,67 +14,63 @@ import NotifierMixin from '../../mixins/notifier'; import TooltipMixin from '../../mixins/tooltip'; const { - computed + computed } = Ember; export default Ember.Component.extend(NotifierMixin, TooltipMixin, { folderService: Ember.inject.service('folder'), - documentService: Ember.inject.service('document'), - session: Ember.inject.service(), + documentService: Ember.inject.service('document'), + session: Ember.inject.service(), appMeta: Ember.inject.service(), showToolbar: false, - folder: {}, - busy: false, - importedDocuments: [], - isFolderOwner: computed.equal('folder.userId', 'session.user.id'), - moveFolderId: "", + folder: {}, + busy: false, + importedDocuments: [], + isFolderOwner: computed.equal('folder.userId', 'session.user.id'), + moveFolderId: "", drop: null, - didReceiveAttrs() { - this.set('isFolderOwner', this.get('folder.userId') === this.get("session.user.id")); + didReceiveAttrs() { + this.set('isFolderOwner', this.get('folder.userId') === this.get("session.user.id")); let show = this.get('isFolderOwner') || this.get('hasSelectedDocuments') || this.get('folderService').get('canEditCurrentFolder'); this.set('showToolbar', show); - let targets = _.reject(this.get('folders'), { - id: this.get('folder').get('id') - }); + let targets = _.reject(this.get('folders'), { + id: this.get('folder').get('id') + }); - this.set('movedFolderOptions', targets); - }, + this.set('movedFolderOptions', targets); + }, didRender() { - if (this.get('hasSelectedDocuments')) { - this.addTooltip(document.getElementById("move-documents-button")); - this.addTooltip(document.getElementById("delete-documents-button")); - } else { - if (this.get('isFolderOwner')) { - this.addTooltip(document.getElementById("folder-share-button")); - this.addTooltip(document.getElementById("folder-settings-button")); - } - if (this.get('folderService').get('canEditCurrentFolder')) { + if (this.get('hasSelectedDocuments')) { + this.addTooltip(document.getElementById("move-documents-button")); + this.addTooltip(document.getElementById("delete-documents-button")); + } else { + if (this.get('isFolderOwner')) { + this.addTooltip(document.getElementById("folder-share-button")); + this.addTooltip(document.getElementById("folder-settings-button")); + } + if (this.get('folderService').get('canEditCurrentFolder')) { this.addTooltip(document.getElementById("import-document-button")); - } - } + } + } }, didUpdate() { this.setupImport(); }, - didInsertElement() { - // this.setupImport(); - }, - - willDestroyElement() { + willDestroyElement() { if (is.not.null(this.get('drop'))) { this.get('drop').destroy(); this.set('drop', null); } - this.destroyTooltips(); - }, + this.destroyTooltips(); + }, setupImport() { // guard against unecessary file upload component init @@ -135,52 +131,52 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { this.set('drop', dzone); }, - actions: { - onDocumentImporting(filename) { - this.send("showNotification", `Importing ${filename}`); + actions: { + onDocumentImporting(filename) { + this.send("showNotification", `Importing ${filename}`); - let documents = this.get('importedDocuments'); - documents.push(filename); - this.set('importedDocuments', documents); - }, + let documents = this.get('importedDocuments'); + documents.push(filename); + this.set('importedDocuments', documents); + }, - onDocumentImported(filename /*, document*/ ) { - this.send("showNotification", `${filename} ready`); + onDocumentImported(filename /*, document*/ ) { + this.send("showNotification", `${filename} ready`); - let documents = this.get('importedDocuments'); - documents.pop(filename); - this.set('importedDocuments', documents); + let documents = this.get('importedDocuments'); + documents.pop(filename); + this.set('importedDocuments', documents); - this.attrs.refresh(); + this.attrs.refresh(); - if (documents.length === 0) { - // this.get('showDocument')(this.get('folder'), document); - } - }, + if (documents.length === 0) { + // this.get('showDocument')(this.get('folder'), document); + } + }, - deleteDocuments() { + deleteDocuments() { this.attrs.onDeleteDocument(); - }, + }, - setMoveFolder(folderId) { - this.set('moveFolderId', folderId); + setMoveFolder(folderId) { + this.set('moveFolderId', folderId); - let folders = this.get('folders'); + let folders = this.get('folders'); - folders.forEach(folder => { - folder.set('selected', folder.id === folderId); - }); - }, + folders.forEach(folder => { + folder.set('selected', folder.id === folderId); + }); + }, - moveDocuments() { - if (this.get("moveFolderId") === "") { - return false; - } + moveDocuments() { + if (this.get("moveFolderId") === "") { + return false; + } - this.attrs.onMoveDocument(this.get('moveFolderId')); - this.set("moveFolderId", ""); + this.attrs.onMoveDocument(this.get('moveFolderId')); + this.set("moveFolderId", ""); - return true; - } - } + return true; + } + } }); diff --git a/app/app/components/section/wysiwyg/type-editor.js b/app/app/components/section/wysiwyg/type-editor.js index e98c2db4..2ad5e6b7 100644 --- a/app/app/components/section/wysiwyg/type-editor.js +++ b/app/app/components/section/wysiwyg/type-editor.js @@ -19,25 +19,23 @@ export default Ember.Component.extend({ appMeta: Ember.inject.service(), link: service(), pageBody: "", - drop: null, - showSidebar: false, didReceiveAttrs() { this.set('pageBody', this.get('meta.rawBody')); }, didInsertElement() { - let self = this; + let maxHeight = $(document).height() - $(".document-editor > .toolbar").height() - 200; let options = { selector: "#rich-text-editor", relative_urls: false, - cache_suffix: "?v=430", + cache_suffix: "?v=443", browser_spellcheck: false, gecko_spellcheck: false, theme: "modern", statusbar: false, - height: $(document).height() - $(".document-editor > .toolbar").height() - 200, + height: maxHeight, entity_encoding: "raw", paste_data_images: true, image_advtab: true, @@ -62,24 +60,9 @@ export default Ember.Component.extend({ menu: {}, menubar: false, toolbar1: "bold italic underline strikethrough superscript subscript | outdent indent bullist numlist forecolor backcolor | alignleft aligncenter alignright alignjustify | link unlink | table image media | hr codesample", - toolbar2: "formatselect fontselect fontsizeselect | documizeLinkButton", + toolbar2: "formatselect fontselect fontsizeselect", save_onsavecallback: function () { Mousetrap.trigger('ctrl+s'); - }, - setup: function (editor) { - editor.addButton('documizeLinkButton', { - title: 'Insert Link', - icon: false, - image: '/favicon.ico', - onclick: function () { - let showSidebar = !self.get('showSidebar'); - self.set('showSidebar', showSidebar); - - if (showSidebar) { - self.send('showSidebar'); - } - } - }); } }; @@ -100,14 +83,17 @@ export default Ember.Component.extend({ }, actions: { - showSidebar() { - this.set('linkName', tinymce.activeEditor.selection.getContent()); - }, - onInsertLink(link) { + let userSelection = tinymce.activeEditor.selection.getContent(); + + if (is.not.empty(userSelection)) { + Ember.set(link, 'title', userSelection); + } + let linkHTML = this.get('link').buildLink(link); tinymce.activeEditor.insertContent(linkHTML); - this.set('showSidebar', false); + + return true; }, isDirty() { diff --git a/app/app/components/ui/ui-checkbox.js b/app/app/components/ui/ui-checkbox.js new file mode 100644 index 00000000..16c8597b --- /dev/null +++ b/app/app/components/ui/ui-checkbox.js @@ -0,0 +1,16 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +import Ember from 'ember'; + +export default Ember.Component.extend({ + tagName: 'span' +}); diff --git a/app/app/services/link.js b/app/app/services/link.js index 1deaf9ef..4c5a2790 100644 --- a/app/app/services/link.js +++ b/app/app/services/link.js @@ -52,3 +52,21 @@ export default Ember.Service.extend({ return result; } }); + +/* + +we should not redirect to a link that is in the same document! + +what happens if we delete attachment? + +UpdatePage(): find and persist links from saved content + + + + +1. We need to deal with links server-side +2. We need to click on links in the browser and 'navigate' to linked content + + + +*/ diff --git a/app/app/styles/app.scss b/app/app/styles/app.scss index 156bf080..c3eb7d18 100644 --- a/app/app/styles/app.scss +++ b/app/app/styles/app.scss @@ -8,14 +8,12 @@ // by contacting . // // https://documize.com - @import "color.scss"; @import "font.scss"; @import "functions.scss"; @import "base.scss"; @import "widget/widget.scss"; @import "view/layout.scss"; -@import "view/content-linker.scss"; @import "view/page-search.scss"; @import "view/page-documents.scss"; @import "view/page-settings.scss"; @@ -27,11 +25,11 @@ @import "view/document/wysiwyg.scss"; @import "view/document/editor.scss"; @import "view/document/wizard.scss"; +@import "view/document/edit-tools.scss"; @import "view/common.scss"; @import "vendor.scss"; @import "responsive.scss"; @import "print.scss"; - @import "section/trello.scss"; @import "section/gemini.scss"; @import "section/github.scss"; diff --git a/app/app/styles/base.scss b/app/app/styles/base.scss index 47906b42..811d0554 100644 --- a/app/app/styles/base.scss +++ b/app/app/styles/base.scss @@ -196,7 +196,7 @@ $i: 100; .width-#{$i} { width: #{$i}#{"%"}; } - $i: $i - 5; + $i: $i - 2; } .no-outline { diff --git a/app/app/styles/view/content-linker.scss b/app/app/styles/view/content-linker.scss deleted file mode 100644 index 501c190e..00000000 --- a/app/app/styles/view/content-linker.scss +++ /dev/null @@ -1,16 +0,0 @@ -.content-linker { - margin: 0 10px; - padding: 20px; - @include border(1px); - - .input-control > .page-list { - margin: 0; - padding: 0; - - > .item { - margin: 0; - padding: 0; - font-size: 0.9rem; - } - } -} diff --git a/app/app/styles/view/document/edit-tools.scss b/app/app/styles/view/document/edit-tools.scss new file mode 100644 index 00000000..59e78607 --- /dev/null +++ b/app/app/styles/view/document/edit-tools.scss @@ -0,0 +1,29 @@ +.edit-tools { + margin: 15px 0 0 20px; + min-height: 500px; +} + +.content-linker-dialog { + width: 300px; + height: 400px; + overflow-y: auto; + + .link-list { + margin: 0; + padding: 0; + + .link-item { + margin: 0; + padding: 5px 0; + font-size: 0.9rem; + color: $color-gray; + cursor: pointer; + + .icon { + margin-right: 5px; + height: 15px; + width: 15px; + } + } + } +} diff --git a/app/app/styles/widget/widget-checkbox.scss b/app/app/styles/widget/widget-checkbox.scss new file mode 100644 index 00000000..f5244023 --- /dev/null +++ b/app/app/styles/widget/widget-checkbox.scss @@ -0,0 +1,21 @@ +.checkbox-option { + vertical-align: bottom; + cursor: pointer; + font-size: 0.9rem; + overflow: hidden; + white-space: nowrap; + + > .material-icons { + font-size: 0.9rem; + vertical-align: top; + margin-right: 5px; + } + + &:hover { + color: $color-link; + } +} + +.checkbox-option-selected { + color: $color-link; +} diff --git a/app/app/styles/widget/widget.scss b/app/app/styles/widget/widget.scss index d867935e..bc0b3b33 100644 --- a/app/app/styles/widget/widget.scss +++ b/app/app/styles/widget/widget.scss @@ -2,64 +2,64 @@ // Material Design icons from https://design.google.com/icons/ .material-icons { - font-family : "Material Icons"; - font-weight : normal; - font-style : normal; - font-size : 1.2rem; - display : inline-block; - text-transform : none; - letter-spacing : normal; - word-wrap : normal; - -webkit-font-smoothing : antialiased; - text-rendering : optimizeLegibility; - -moz-osx-font-smoothing: grayscale; - font-feature-settings : "liga"; + font-family: "Material Icons"; + font-weight: normal; + font-style: normal; + font-size: 1.2rem; + display: inline-block; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + -moz-osx-font-smoothing: grayscale; + font-feature-settings: "liga"; } .transition-shadow { - transition: box-shadow .25s; + transition: box-shadow 0.25s; } .transition-all { - transition: all .25s; + transition: all 0.25s; } .z-depth-0 { - box-shadow: none !important; + box-shadow: none !important; } .z-depth-tiny { - box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05), 0 1px 1px 0 rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05), 0 1px 1px 0 rgba(0, 0, 0, 0.05); } .z-depth-half { - box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.16), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.16), 0 1px 5px 0 rgba(0, 0, 0, 0.12); } .z-depth-1 { - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); } -.z-depth-1-half { /* used on hover states */ - box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15); +.z-depth-1-half { + /* used on hover states */ + box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15); } .z-depth-2 { - box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); } .z-depth-3 { - box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19); + box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19); } .z-depth-4 { - box-shadow: 0 16px 28px 0 rgba(0, 0, 0, 0.22), 0 25px 55px 0 rgba(0, 0, 0, 0.21); + box-shadow: 0 16px 28px 0 rgba(0, 0, 0, 0.22), 0 25px 55px 0 rgba(0, 0, 0, 0.21); } .z-depth-5 { - box-shadow: 0 27px 24px 0 rgba(0, 0, 0, 0.2), 0 40px 77px 0 rgba(0, 0, 0, 0.22); + box-shadow: 0 27px 24px 0 rgba(0, 0, 0, 0.2), 0 40px 77px 0 rgba(0, 0, 0, 0.22); } - @import "widget-avatar"; @import "widget-button"; @import "widget-card"; @@ -70,3 +70,4 @@ @import "widget-sidebar-menu"; @import "widget-table"; @import "widget-tooltip"; +@import "widget-checkbox"; diff --git a/app/app/templates/components/document/edit-tools.hbs b/app/app/templates/components/document/edit-tools.hbs new file mode 100644 index 00000000..890ef044 --- /dev/null +++ b/app/app/templates/components/document/edit-tools.hbs @@ -0,0 +1,44 @@ +
+ +
+ link +
+ + {{#dropdown-dialog target="content-linker-button" focusOn="content-linker-search" position="bottom right" button="Insert" color="flat-blue" onAction=(action 'onInsertLink')}} +
+
+
+ +
Choose content below or search
+ {{focus-input id="content-linker-search" type="input" value=keywords placeholder="keyword search"}} +
+ {{#if hasSections}} + + {{/if}} + {{#if hasAttachments}} + + {{/if}} +
Insert
+
+ +
+ {{/dropdown-dialog}} + +
diff --git a/app/app/templates/components/folder/folders-list.hbs b/app/app/templates/components/folder/folders-list.hbs index 97969810..844dd399 100644 --- a/app/app/templates/components/folder/folders-list.hbs +++ b/app/app/templates/components/folder/folders-list.hbs @@ -4,12 +4,7 @@ close
- {{folder/start-document - savedTemplates=savedTemplates - folder=folder - editor=folderService.canEditCurrentFolder - onEditTemplate=(action 'onEditTemplate') - onDocumentTemplate=(action 'onDocumentTemplate')}} + {{folder/start-document savedTemplates=savedTemplates folder=folder editor=folderService.canEditCurrentFolder onEditTemplate=(action 'onEditTemplate') onDocumentTemplate=(action 'onDocumentTemplate')}} {{/if}} {{#if showScrollTool}} @@ -35,7 +30,7 @@ add
Space
- {{#dropdown-dialog target="add-space-button" position="bottom left" button="Add" color="flat-green" onAction=(action 'addFolder') focusOn="new-folder-name"}} + {{#dropdown-dialog target="add-space-button" position="bottom left" button="Add" color="flat-green" onAction=(action 'addFolder') focusOn="new-folder-name" }}
@@ -92,8 +87,6 @@ {{/if}}
- - diff --git a/app/app/templates/components/link/content-linker.hbs b/app/app/templates/components/link/content-linker.hbs deleted file mode 100644 index d5708fc1..00000000 --- a/app/app/templates/components/link/content-linker.hbs +++ /dev/null @@ -1,21 +0,0 @@ -
-
-
- -
Give the link a clickable name
- {{focus-input type="input" value=linkName}} -
- {{#if hasSections}} -
- {{ui-select id="content-linker-section-list" content=candidates.pages action=(action (mut selection)) prompt="Link to existing section" optionValuePath="id" optionLabelPath="title" }} -
- {{/if}} - {{#if hasAttachments}} -
- {{ui-select id="content-linker-attachment-list" content=candidates.attachments action=(action (mut selection)) prompt="Link to file attachment" optionValuePath="id" optionLabelPath="title" }} -
- {{/if}} -
Insert
-
- -
diff --git a/app/app/templates/components/section/wysiwyg/type-editor.hbs b/app/app/templates/components/section/wysiwyg/type-editor.hbs index d298ea74..0e84aabf 100644 --- a/app/app/templates/components/section/wysiwyg/type-editor.hbs +++ b/app/app/templates/components/section/wysiwyg/type-editor.hbs @@ -1,10 +1,11 @@ {{#section/base-editor document=document folder=folder page=page isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}} -
+ +
{{focus-textarea value=pageBody id="rich-text-editor" class="mousetrap"}}
-
- {{link/content-linker document=document folder=folder page=page linkName=linkName onInsertLink=(action 'onInsertLink')}} +
+ {{document/edit-tools document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}}
{{/section/base-editor}} diff --git a/app/app/templates/components/ui/ui-checkbox.hbs b/app/app/templates/components/ui/ui-checkbox.hbs new file mode 100644 index 00000000..df570907 --- /dev/null +++ b/app/app/templates/components/ui/ui-checkbox.hbs @@ -0,0 +1,8 @@ +
+ {{#if selected}} + radio_button_checked + {{else}} + radio_button_unchecked + {{/if}} + {{yield}} +
diff --git a/core/api/endpoint/link_endpoint.go b/core/api/endpoint/link_endpoint.go index 26f4b946..1472ffa9 100644 --- a/core/api/endpoint/link_endpoint.go +++ b/core/api/endpoint/link_endpoint.go @@ -94,11 +94,12 @@ func GetLinkCandidates(w http.ResponseWriter, r *http.Request) { for _, f := range files { c := entity.LinkCandidate{ - RefID: util.UniqueID(), - DocumentID: documentID, - AttachmentID: f.RefID, - LinkType: "file", - Title: f.Filename, + RefID: util.UniqueID(), + DocumentID: documentID, + AttachmentID: f.RefID, + LinkType: "file", + Title: f.Filename, + AttachmentExtension: f.Extension, } fc = append(fc, c) diff --git a/core/api/entity/objects.go b/core/api/entity/objects.go index 78432c80..7c00bdd7 100644 --- a/core/api/entity/objects.go +++ b/core/api/entity/objects.go @@ -346,23 +346,25 @@ type SitemapDocument struct { // Link defines a reference between a section and another document/section/attachment. type Link struct { BaseEntity - OrgID string `json:"orgId"` - UserID string `json:"userId"` - SourceID string `json:"sourceId"` - DocumentID string `json:"documentId"` - PageID string `json:"pageId"` - LinkType string `json:"linkType"` - Orphan bool `json:"orphan"` + OrgID string `json:"orgId"` + UserID string `json:"userId"` + LinkType string `json:"linkType"` + SourceID string `json:"sourceId"` + DocumentID string `json:"documentId"` + PageID string `json:"pageId"` + AttachmentID string `json:"attachmentId"` + Orphan bool `json:"orphan"` } // LinkCandidate defines a potential link to a document/section/attachment. type LinkCandidate struct { - RefID string `json:"id"` - OrgID string `json:"orgId"` - DocumentID string `json:"documentId"` - PageID string `json:"pageId"` - AttachmentID string `json:"attachmentId"` - LinkType string `json:"linkType"` - Title string `json:"title"` // what we label the link - Context string `json:"context"` // additional context (e.g. excerpt, parent) + RefID string `json:"id"` + OrgID string `json:"orgId"` + LinkType string `json:"linkType"` + DocumentID string `json:"documentId"` + PageID string `json:"pageId"` + AttachmentID string `json:"attachmentId"` + AttachmentExtension string `json:"attachmentExtension"` + Title string `json:"title"` // what we label the link + Context string `json:"context"` // additional context (e.g. excerpt, parent) } diff --git a/core/api/request/link.go b/core/api/request/link.go index 8fcc5e7a..0f829aea 100644 --- a/core/api/request/link.go +++ b/core/api/request/link.go @@ -136,3 +136,30 @@ func (p *Persister) DeleteLink(id string) (rows int64, err error) { // // return // } +// +// package main +// +// import ( +// "fmt" +// "regexp" +// ) +// +// var imgRE = regexp.MustCompile(`]+\bhref=["']([^"']+)["']`) +// +// func findImages(htm string) []string { +// imgs := imgRE.FindAllStringSubmatch(htm, -1) +// out := make([]string, len(imgs)) +// for i := range out { +// out[i] = imgs[i][1] +// } +// return out +// } +// +// func main() { +// fmt.Printf("%q", findImages(data)) +// } +// +// const data = ` +//

dfdfdf

+// +// `