Releases: portone-io/docx-editor
Release list
@portone/docx-editor@0.6.0
Minor Changes
-
#131
5dd468aThanks @Deea222! - A comment now outlives the text it was written for, and a resolved one stops marking the page.Deleting commented text used to delete the comment and everything said under it. The thread now
stays. Trim the highlighted text - type over part of it, backspace through its edge - and the
comment follows what is left. Delete all of it and the comment comes back detached: no longer drawn
beside the page, since there is nothing to draw it next to, and listed under All comments marked
"Original content deleted". Cutting commented text leaves it behind the same way instead of dropping
it. Word has no detached state, so such a comment reaches the saved file as an ordinary comment
sitting where the deleted text was. Deleting a comment from its own Delete button still deletes it,
and undo and redo still take a deletion back and make it again.Resolving a thread now takes its highlight off the text, and reopening puts it back. Clicking a
resolved comment's card in All comments selects the text it was written about and scrolls it into
view, whichselectCommentnow does for every caller.documentCommentsreports a newanchoredfield on every comment,falsefor one that no longer
marks a stretch of the document. Its existing fields are unchanged, so a panel of your own keeps
working and can read the new field to decide what a click on a card should do.
@portone/docx-editor@0.5.1
Patch Changes
-
#125
88ff33aThanks @Deea222! - Pasting from Word, Google Docs or LibreOffice now keeps tables as tables and Word lists as lists.A table on the clipboard used to arrive as a single paragraph holding the text of every cell run
together. It now arrives as a table: one paragraph for each block a cell held, the columns and rows
a cell reached across kept, and the same width and lines a table inserted here has.Word writes list items as ordinary paragraphs that name the list they belong to and draw their own
bullet or number, so pasting one used to give unnumbered paragraphs each beginning with a stray
marker. The items of one Word list now join one list, at the level Word gives them, counted when
the marker Word drew counts.A table's caption is kept as the paragraph above it, a table inside a list item is read as a table
rather than as the item's own text, and a table too large for the editor to hold is read as one
paragraph per row instead of as a single run-on one.A copy wrapped in a single element, which is how Google Docs writes one, no longer has its
paragraphs pressed into one. -
#123
3d6b0a5Thanks @Deea222! - Copied HTML and text now follow one declared outbound shape per node and mark, so what leaves the editor is decided beside the schema rather than filtered out of the page's own drawing afterwards. A copy pasted into another application carries paragraphs, styles, runs, links, images at the size they were drawn, and tables as tables, and none of the document's internals. A comment marker, a bookmark, and the placeholder standing for content the editor could not model now leave nothing behind them, where before they left an element carrying the editor's own name for what stood there.Copied plain text reads as the page does. A table pasted into a spreadsheet keeps one row per row, with everything a cell holds on the one line that cell stands on, and a block the editor only kept no longer opens a blank line where it stood. A kept line break and a kept character, such as a no-break hyphen, travel with the text they stand in, and so does the text a placeholder draws: a field's cached result and the words of a tracked insertion read in a copy as they read on the page.
-
#124
936b2a0Thanks @Deea222! - Hyperlinks that hold content controls, and nested controls, open as editable text.Only one of the arrangements used to be readable - a control holding a link. A link holding a
control, or a control holding a control, brought the inner one in as a small box naming the element
it stood for, and the text it held could not be typed in. Any depth and any order of the two is now
ordinary text wearing a wrapper each, and goes back out nested as it came. A hyperlink inside a
hyperlink is the one arrangement still kept whole, since a link marks the text it covers once.A link made on text inside a control is written inside that control, and a lock put on a stretch
that sits wholly inside a link is written inside that link, instead of either wrapper being split
around the other. Where a control holds a control, locking shuts the outer one and lifting a lock
opens the inner one the selection stands in.Plugins reading the drawn page will find
data-keyanddata-depthon a control and a link in
place ofdata-sdt-keyanddata-link-key.
@portone/docx-editor@0.5.0
Minor Changes
-
#105
efe7dbfThanks @Deea222! - Keep markup the editor cannot model where it stood, instead of standing the paragraph around it down.Opening a document used to walk a handful of element names and give up on the rest, and giving up
travelled outward until a whole paragraph became an "Unsupported content" placeholder. A word
processor writes aw:lastRenderedPageBreakon every page it lays out, so a real document opened
with one locked paragraph per page.Every level of the document now has a preservation rule of its own. A run child stays inside its
run, a paragraph child beside the runs, a block stays a block, and only a marker or a wrapper
standing between the rows or the cells of a table - where there is no node to keep it in - still
stands the table down. What is left shows as a small box naming the element it stands for, or as
nothing where the file drew nothing, and the paragraph around it stays editable.- A field code and its drawn result, a tracked insertion or deletion, a symbol, a positional tab
and a content control the editor could not take apart are visible where they stand. - Bookmarks, permission ranges, the markers of a moved passage and the pieces of a field cannot be
removed by an edit; a tracked-change container, a simple field and a symbol can be selected and
deleted whole. documentFidelityand thenotesofimportDocxnow reportpreserved-run-content, and no
longer reportparagraph-demotedfor a document being opened.- New node
rawRunContent, andrawInlinegains the attrselement,display,textand
guarded. A plugin reading the document model sees both. - A footnote body, a comment body and a header now read a
w:crand aw:noBreakHyphenthe way
the document body does.
- A field code and its drawn result, a tracked insertion or deletion, a symbol, a positional tab
-
#106
f2871cdThanks @Deea222! - The comment composer keeps the text it was opened over while the document is edited elsewhere, and closes when that text is deleted or the mode turns read-only. The comment is written on that text rather than on whatever is selected when the writer submits.Opening the composer no longer scrolls the document back to its first page.
addCommentandcanAddCommenttake an optional{ from, to }range as their last argument, which a composer of your own can hold across edits the same way; the current selection is still used when none is given. -
#116
4d9964dThanks @Deea222! - Comment bodies keep their formatting when edited, andsetCommentBodyaccepts a formatted body.Breaking: the
commentReferencenode loses itstext,commentXmlandimportedattrs and
thenoteReferencenode loses itstextattr, together with thedata-comment-text,
data-comment-xml,data-comment-importedanddata-note-textattributes that carried them into
the DOM. A plugin that matched any of those reads what a comment or a note says through
documentCommentsanddocumentNotesinstead, which answer as they always did.Breaking:
DocumentComment,DocumentCommentReplyandDocumentNotedeclare every field
readonly. They are the editor's own records, worked out once per edit and handed out rather than
copied, so a caller that was writing into one copies it first.A side story - a comment's body, a footnote's - is now read the way the document body is: the same
block readers, the same verbatim slices, one document of the editor's own schema per story. It
stands on the document node underdoc.attrs.stories, so an edit to it rides a transaction and
lands in the history, and everything the edit did not touch is written back as the bytes it arrived
as. Editing a comment used to flatten its body to plain text and rewrite it as one run, which lost
its bold, its paragraph style and its second paragraph.setCommentBody(id, body)is a new command on./commands. It takes adocnode ofdocxSchema,
which is what a composer of your own builds a formatted body as;updateComment(id, text)stays
what it was for a body that is only text.Dropping those attrs is what the story replaces them with: what a comment or a note says is no
longer written on the node marking where it stands, so nothing has to keep the two in step, a copy
of the node no longer carries the body along with it, and neither reaches the clipboard. -
#108
d783e24Thanks @Deea222! - Keep a table whose markers stand between its rows or its cells, and stand every block the editor
cannot model as one kind of placeholder.Breaking: the
docxRawandbookmarkBlocknode types no longer exist. Both were placeholders
for a block nobody could read, differing only in where the block stood and whether anything of it
was drawn, andrawBlockis now the one node for all of them. A plugin that matched either name
matchesrawBlockinstead and readsdisplay("chip"for a placeholder box,"hidden"for a
marker that draws nothing) andguardedto tell them apart. The class names
docx-editor-bookmark-block,docx-editor-raw-xmlanddocx-editor-tableare gone with them;
every placeholder now draws asdocx-editor-raw-block.- A bookmark spanning a table column stands under the row rather than inside a cell, and used to
cost the whole table its structure. Such a table now opens as a table, and the marker goes back
exactly where it stood. A marker following a cell that only continues a vertical merge is the
remaining exception, since that cell is created fresh on export. documentFidelityand thenotesofimportDocxno longer reporttable-demotedfor a table
whose only unread markup is a marker.- A placeholder can now be moved between the body and a table cell and still export.
tableandtableRowgain aleadingXmlattr,tableRowandtableCellatrailingXmlattr:
the markers each carries between its children.
Table markers remain protected against deletion, duplication and reordering, including markers
whose ranges cross into a cell paragraph. Export checks read those fragments in document order. - A bookmark spanning a table column stands under the row rather than inside a cell, and used to
Patch Changes
-
#109
05e9431Thanks @Deea222! - Cache comment and note lists between document edits. Public readers continue to return independent comment, reply, and note records, so changes to their results cannot alter the editor's cached data. -
#118
7de8870Thanks @Deea222! - Every section now previews the headers and footers it names. A document whose second section
selects a header of its own used to draw the first section's on every page, because only the first
section's references were ever resolved.A header and a footer body is read the way the document body is: the same block readers, the same
verbatim slices, one story per part on the document node beside the comment and footnote stories.
The plain-text walker each of them used to have is gone, so aw:cr, a no-break hyphen and a field
read the same in a header as they do anywhere else, and aPAGEorNUMPAGESfield is now found by
pairing the field characters it is written between rather than by scanning the text they surround.A header story the editor rewrote is written back into its own part, around the two ends that part
arrived with, and every part nobody rewrote is repacked as the bytes it came as. Editing a header is
not offered in the editor yet; this is the model and the export path underneath it. -
#115
9c5331dThanks @Deea222! - Copying and pasting inside the same document now keeps what it was copied as: paragraph and character formatting, tabs, breaks, images, links, and whole tables, instead of the part an HTML reader could make out. Copying a grid of cells and pasting it over selected cells fills them in place. Comment markers, bookmarks, and note references are not copied, so cutting and pasting them back drops them. A pasted list whose numbering the document no longer defines is given a number that it does, keeping the bullets or numbers it was copied with; a list arriving from another document or application is renumbered by the reader that reads it. Content copied from another document, including a second editor on the same page, still comes in through that reader. -
#119
9b4b3fcThanks @Deea222! - Page boundaries and table widths now follow the paper of the section a block sits in. A document
whose second section is landscape used to be paginated as though the whole of it were the first
section's portrait paper, and a table put in that section was...
@portone/docx-editor@0.4.0
Minor Changes
-
#102
4258530Thanks @Deea222! - Draw the table styles and list numbering a document defines, and let a document that never held a list take one.A table style is now displayed part by part: the header row, the closing row, the first and last column, the corners and the banded rows take the shading, the lines and the text formatting the style dresses them with (
w:tblStylePr), andw:tblLookdecides which of those parts a table takes.
The bands are as many rows or columns wide as the style says (w:tblStyleRowBandSize,w:tblStyleColBandSize), and the header row and the closing row are not banded with the rest.
Text already in a cell follows its new position after a row edit, and the conditional-formatting markup a document arrived with goes back out untouched.A list that takes its numbers from a numbering style now draws them.
Such a list holds no numbers of its own: it names a style (w:numStyleLink), the style names a list, and that list's definition is where the numbers are, which is how Word writes a list built from its gallery.
Alongside decimal, bullets, upper and lower letters and lower Roman numerals, a list may now count in upper Roman numerals, decimal numbers with a leading zero, Ganada, Korean digits and the Chinese counting system; a format past those is still shown with decimal numbers.
Each level is drawn the way it asks to be: where its counting starts over (w:lvlRestart), whether the numbers in its text are all spelled as decimals (w:isLgl), what stands between its number and the paragraph text (w:suff), and where the number sits in the room kept for it (w:lvlJc).
A marker is also drawn in the character formatting its own level writes down (lvl/rPr), so bold, italic, color, size and typeface reach the number and never the text of the paragraph it stands in front of.
All of this is read; the numbering part goes back out exactly as it arrived.A new list no longer needs the document to have arrived with a numbering part.
The export writesword/numbering.xml, relates it from the main part and declares it in the content types, so a document that never held a list can take one; the list commands, which used to report that they did not apply in such a document, now do.
If an existing numbering relationship points to a missing part, the new definition is written at that location so the document can find the list when it is reopened.A new or pasted list is exported with the definition it was started with, rather than a format inferred from its numbering IDs, and undo restores that registration along with the edit.
A list whose definition is missing or unsupported is refused asunsupported-content, and a package with no[Content_Types].xmlfor the new numbering part to be declared in is refused asmissing-content-types;exportProblemsreports either ahead of the write.
List and abstract definition IDs stay distinct in a document already using the largest safely representable integer, and a value that cannot be written faithfully is rejected rather than silently changed or discarded.An ECMA-376 Strict package is refused with the new
unsupported-conformancecode, and a document whose main part root does not bindwto Transitional WordprocessingML is refused asunsupported-content.
Word saves neither by default, and both used to open far enough to fail later and obscurely: a Strict package asmissing-part, and a document under another prefix as amalformed-xmlabout bookmarks on its first edit.
A write needing a prefix already bound to a different namespace is refused instead of silently giving new markup the wrong meaning, and a new hyperlink relationship attribute is checked for a declaration that shadows the root binding.
The comment and hyperlink writers now have the part's root declare the prefix they write under rather than declaring it on every element written, and editing an existing numbering or comment extension part that uses another prefix adds the writer's declaration at the root, so an untouched document still exports byte for byte and the exported XML stays readable.DocxImportErrorCodegainsunsupported-conformance.
DocxExportErrorCodelosesmissing-numbering-part, since nothing can reach it any more, and that is a compile error for aswitchover the code written to be exhaustive; drop the branch.
missing-content-typesnow also covers the numbering part a new list is defined in.
On./core,Numberinggainsadded, and the newNewListandNewListLeveltypes describe the definitions the editor registered.
Level maps are read-only, and a registered definition carries a restart, legal numbering and a suffix, while marker run formatting and custom tab stops stay outside what can be registered.
Patch Changes
-
#101
1b6c723Thanks @Deea222! - Stop drawing the page number on the corner of each page.The page guides laid a small grey number inside the top right corner of every page, over the paper the text sits on.
It is gone, and the guides now draw the gaps between pages and the header and footer stories alone.
A document that prints its own page number through aPAGEfield in a header or footer is unaffected: that number is the document's, not the editor's.The
docx-editor-page-badgeclass the number carried is no longer emitted, so a rule of your own written against it in the published stylesheet no longer matches anything.
@portone/docx-editor@0.3.0
Minor Changes
-
#62
5c481e7Thanks @Deea222! -onlyCommentsChangedByanswerscomment-markup-rejectedwhere it used to answerpart-changedfor a comment part entry this editor would not have written for this author, or an entry nothing refers to that changed.partstill names the comment part the entry sits in.The verdicts themselves are unchanged: every file accepted before is accepted now, and every file refused before is refused now. What moves is the name a server logs, so "a part this file was not supposed to touch" and "markup forged into a comment" no longer read alike. A
switchoververdict.reasonneeds the new case. -
#77
a0b5cc6Thanks @Deea222! - Ask whether a document can be exported before trying.exportProblems(doc, session)on the core entry, andcanExport(state)withdocumentExportProblems(state)on the commands entry, report known reasons the writer would refuse the document, in the order it would raise them: each under the code and with the message theDocxExportErrorwould carry, and with its position where the problem stands in the document.exportDocxthrows the first entry of the same list, so problems reported by the query are also refused by the write.The editor's handle answers the same list as
exportProblems()besideexportBytes(), anddownloadDocxasks it first and returns{ status: "blocked", problems }instead of throwing. A refusal the list does not foresee, such as a node a plugin stripped of an attribute the writer needs, is still thrown.DownloadDocxResultgaining a fourth member is a compile error for aswitchoverstatuswritten to be exhaustive; add ablockedbranch that shows the problems.A document whose comments part arrived as an empty element used to refuse its first comment with
malformed-xml, since the writer looked for a closing tag the element does not have; the part is now opened for the entry, the way an empty extended comments part already was. -
#63
1a4ec92Thanks @Deea222! - Read what a document holds that this editor cannot model.importDocxreturns anotesarray alongside the document and the session, the newexportDocxReportreturns the same list beside the bytes it writes, and the newdocumentFidelity(state)on./commandsanswers the question about the document standing in an editor. AFidelityNotesays how much of the original survived, what kind of content it was, the part and body block it came from, where in the document it stands, and the original element name, so a host can list what a file lost instead of guessing at it. DestructuringimportDocxis unaffected.A table now carries its
w:tblGridChangeinstead of losing it whenever the table is rebuilt. The grid is still written from the column widths, and the revision markup closes it where CT_TblGrid takes it.onlyCommentsChangedBytherefore catches a submission that lost aw:tblGridChange, where it used to accept one: a returned file that dropped it now answersbody-changedrather thanok. -
#79
70d4801Thanks @Deea222! - Applying a paragraph style keeps the spacing the document defaults lay down, and formatting a style or the document defaults switch on can be switched off: the off is written into the run (w:b w:val="0") and drawn as off, where it used to be dropped and the style's value drawn again.Every display value a paragraph or a run carries is now resolved in the ECMA-376 §17.7.2 order by one resolver, whichever path built the paragraph: opening the document, applying a style, a paragraph edit, a paste, or typing into a fresh paragraph. A character style a run points at (
w:rStyle) takes its place in that order, a hanging indent's implicit tab stop follows the indent actually drawn, and a document'sw:noTabHangIndsetting switches that stop off.RunFormatgrows to say so:bold,italic,strikeandsmallCapsareboolean(false is a toggle the run switches off outright), andunderlinemay be"none". A reader checking=== trueor a truthy value is unaffected.Supported character defaults now appear in the text and toolbar, so a default bold setting turns off with one press. Clearing a direct font size immediately restores the inherited paragraph or character style in the formatting controls.
-
#82
f804ba1Thanks @Deea222! - A paragraph marked keep with next (w:keepNext), by its own properties or by its style, stays on the same page as the start of the block after it in the page guides, as it does in Word. A run of such paragraphs moves together with the first piece of the block the keeps end at; a run no page can hold is laid out as if no keep were set. The document is not changed: the mark is read, never written.ParagraphFormatgrowskeepNext?: booleanto say so, besidepageBreakBefore.An explicit off (
w:keepNext w:val="0") overrides an inherited keep, so a paragraph can opt out of the keep imposed by its style. -
#80
a37b4feThanks @Deea222! - Run formatting is read, written and compared through one property table, so the value a control reads, the XML an edit writes and the check that leaves text already in that state alone can no longer drift apart. The XML written is byte for byte what it was.RunFormatgainscaps,doubleStrikeandcharacterSpacingPt, read off a run'sw:caps,w:dstrikeandw:spacing. They reach theformatattr a plugin reads; the editor does not draw or edit them yet.An underline setter now distinguishes underline kinds; the public underline toggle still turns any existing kind off.
-
#72
578e73eThanks @Deea222! -srcIdnow names the block within the session it was opened in. A preserved block used to carry a bare index into the blocks of whichever document it was exported against, so a block moved or pasted in from another document pointed at this document's block of the same number and went out as that block's XML instead of its own. The attribute is now a string naming the document, the story and the place in it, and a block whose document is not the one being exported is refused withlost-originalrather than written as something else.A plugin that read
node.attrs.srcIdas a number needs to change: it is a string, and the only thing to do with it is hand it back as it was found. Nothing else about the attribute is public, and no exported type or function signature changed. -
#60
1b5d0fdThanks @Deea222! - HandimportDocx,exportDocx,onlyCommentsChangedBy,documentNumberingandparseNumberinganxmlParserto read a document on a runtime that has noDOMParserglobal, instead of installing one.A call given neither is refused with
DocxImportErrorand the new import codeno-xml-parser. It used to fail with a bareReferenceError, which a server checking a file a counterparty returned could not tell apart from a document that arrived damaged. Reading a document no longer asks for aNodeglobal at all, soDOMParser, however it is supplied, is the only thing the core entry needs from a DOM.Each entry point settles its parser as the call comes in, so a runtime holding none is turned down before the bytes are looked at: bytes that are not a docx opened without a parser now report
no-xml-parserwhere they reportednot-a-docx. A parser that answers markup it cannot read by throwing, rather than by handing back a document holding aparsererror, is read asmalformed-xmlinstead of having its own exception reach the caller.
Patch Changes
-
#75
c79e417Thanks @Deea222! - Document which schema attributes plugins may rely on and which raw OOXML attributes are internal.
An internal classification now records the provenance of every node and mark attribute without changing import, editing, or export behavior. -
#65
a9a7e6dThanks @Deea222! - Content control properties are written in the order the schema lays down. Locking a control that declares what kind of control it is - a date picker, a drop-down, plain text - used to writew:lockafter that declaration, where CT_SdtPr putsw:lockbefore it, so a validator reading the exported file could refuse a control this editor had rewritten. ...
@portone/docx-editor@0.2.1
Patch Changes
-
#53
d264803Thanks @Deea222! - Stop text copied out of the editor from carrying the document's private data.A copy was drawn the way the editor draws itself, so the HTML it left on the clipboard held the paragraph and run XML, the name and recorded identity of a comment's author, what the comment and its replies say, and the body of a footnote.
All of it landed in whatever application it was pasted into, and incommentmode a reader who may not change the body could take the body out this way.
A copy now carries only what a reader of it needs, and the paragraph style it names is the style's id rather than the wholew:pPr.
A link goes out as a link, so it can be followed where it lands and comes back as one when it is pasted here again.The plain text beside it says what was copied: a tab is a tab, a line break is a line, a page break is a form feed, and a table's cells stand apart by a tab and its rows by a line, so a table pasted into a spreadsheet arrives as a table.
A cell holding a line break is the exception, since the line inside it reads as the start of the next row. -
#50
41d82c5Thanks @Deea222! - StoponlyCommentsChangedByfrom excusing a part a submission relates as a comment part.The three comment parts are left out of the byte comparison, and which parts those were came from the submitted file's own relationships.
A file could relate a second comments, extended comments or people part at any part it liked and have that part go uncompared, so a rewritten styles part, a settings part pointing at a template off the package, replaced image bytes or forged document properties were all reported as a change to nothing but comments.
The parts left out are now the ones the reader opened, a comment part may be related once, one related for the first time has to be a part the submission brought with it, and a relationship part naming one id twice is turned down.A file that relates an extended comments part but carries no comments part now has that part read, so writing the first comment into it writes that part rather than a second one beside it.
Two extended parts related at once was a file whose settled threads a reader would lose, since only the first of them is read.This affects 0.2.0. A server that accepted files on this verdict should upgrade and run the check again over what it accepted, where such a file now answers
part-changednaming the part, orrelationship-changednaming the relationship part. -
#56
467f6f5Thanks @Deea222! - Commands andcanRunCommandnow report false where a bookmark marker or a note reference would be removed, instead of reporting true and changing nothing.A refusal over one of those markers also ends an open IME composition, the way a refusal over a locked control already did.
-
#59
6d7b97fThanks @Deea222! - Formatting XML is now written through shared primitives that consistently escape attribute values while preserving existing formatting behavior. -
#58
d9edb75Thanks @Deea222! - Pagination measures every block as a list of break candidates; no visible change -
#55
7110baaThanks @Deea222! - Turn down a raw OOXML fragment that does not hold its shape as it enters the document, rather than writing it into the exported file.Keep imported formatting when a document uses an inherited default namespace or an alternative WordprocessingML prefix. Reject nested namespace rebinding that could disconnect hyperlinks from their targets on export.
The editor draws the original XML of a paragraph, a run, a table, an image or an annotation into the page as a
data-attribute, so that it can read the live DOM back after an IME composition or a browser edit. A fragment written into one of those attributes from outside, by a consumer plugin or throughview.pasteHTML, is now held to what that attribute goes back out as: a whole element under an expected name, an opening tag's attributes, or an opening tag the writer closes itself. One that does not hold it is turned down along with the rule reading it, so the content settles one level plainer - a paragraph keeps its text and loses its properties, a run loses its mark, a content control or a hyperlink loses its wrapper - instead of adata-pprreading</w:p><w:p>...writing a second paragraph into the exported body, or one that never closed reaching export and failing the whole document withmalformed-xml. -
#54
8aea477Thanks @Deea222! - An untouched table opened in the editor is written back byte for byte, itsw:tblGridChangeincluded.Export decided whether a block was untouched by comparing it with the one import produced, attrs and all.
Opening a document works some of those attrs out again from the formatting around them - a table's shared cell borders among them - so a table nobody had touched compared unequal and was rebuilt, and the rebuild dropped the markup the writer does not model.Each attr now declares whether the writer writes from it, whether the editor works it out for the screen, or whether it identifies something in the open document, and the comparison ignores the ones worked out for the screen.
Exporting throughcreateEditorStateis held to the same byte identity as exporting straight fromimportDocx. -
#48
de84006Thanks @Deea222! - StoponlyCommentsChangedByfrom refusing a comment written into a table cell.A commented table is rebuilt on the way out, so it came back worded the way this editor words it while the original carried the wording its producer chose, and the two were compared word for word.
The story is now compared as this editor writes it back, so two blocks this editor would write alike are read alike: the attribute order inside aw:tcWor aw:tblW, a percentage width written as100%or as5000, runs a producer split that say the same text, and a table'sw:tblGridChange.
Formatting properties keep the line breaks, comments and text a producer wrote between them, so rewriting a run's bold, a paragraph's alignment or a cell of a rebuilt table no longer drops them.
A rebuilt table keeps what stood inside its width and span properties too. -
#52
991ba48Thanks @Deea222! - Read the comment parts entry by entry inonlyCommentsChangedBy.The three parts a comment is written across are the ones a comment edit may rewrite, so the package comparison passes over their bytes.
Nothing read them afterwards, which let a submission carry a field pointing at a remote image inside a comment body, a comment attributed to a third author that nothing refers to, or markup wrapped around a body, and still be answered as a file where only comments changed.
Each entry now has to arrive as it was, or be one this editor writes for an author who could have written it, and an entry nothing refers to has to stay as it was.
A file that fails is refused aspart-changednaming the comment part.Settling or replying to a comment that arrived with the file no longer rewrites its entry as plain text.
The entry keeps what it said, and its last paragraph gains thew14:paraIdthe thread state is written against.
The extended comments part carries an entry only for a comment that has thread state.
@portone/docx-editor@0.2.0
Minor Changes
-
#45
3190a35Thanks @Deea222! - Add acommentmode and record who wrote each comment.Breaking:
modeis now required and thecommentAuthorprop is removed.
author: { id, name, initials? }moves intomodefor itscommentandeditkinds.
contextMenusmoves offmodeontoDocxEditoritself, somode: { kind: "edit", contextMenus: false }becomescontextMenus={false}.In
commentmode the text can be selected and copied but not changed, while comments can be written, answered, resolved, and reopened.
A comment records its author's identity in the document, so two authors sharing a display name stay distinct.
Only a comment's author may edit or delete it, and anyone may reply, resolve, and reopen.
mode.editableComments: "all"opens every comment to a moderator.
ThecanEditCommentandeditingProtectionqueries report what the current mode allows.
A server can check a file coming back withonlyCommentsChangedByfrom@portone/docx-editor/core, which answers{ ok: true }or{ ok: false, reason }for whether the file differs in nothing but one author's comments.
@portone/docx-editor@0.1.1
Patch Changes
-
#36
ab518b9- Read two Unicode spellings of one font name as the same font.A name a document writes down can be composed or decomposed (NFC or NFD) while the same name elsewhere in the document, or among the toolbar's presets, is written the other way.
Those spellings used to compare unequal, so the font dropdown listed the same font twice and a selection that all carried one font could report as mixed and blank the dropdown.
Names are now compared in composed form, and the spelling the document wrote is what stays stored, exported, and shown.A list marker cut to its length cap is also cut between characters now, instead of possibly splitting an emoji or a combining sequence in half and drawing a replacement glyph.
@portone/docx-editor@0.1.0
The first release.
The documentation covers what the editor edits, what it preserves untouched, and its current limitations.
Install it from npm as @portone/docx-editor.