Phát hành Wordgard 0.1
(marijnhaverbeke.nl)- Wordgard 0.1 là một thư viện trình soạn thảo văn bản giàu định dạng bằng JavaScript mới, phản ánh 9 năm kinh nghiệm kể từ khi ProseMirror ổn định và thiết kế của CodeMirror 6
- Thay vì biến ProseMirror hiện có thành 2.0 hoặc chắp thêm vào 1.x, dự án được thiết kế lại với tên riêng và API mới không chịu gánh nặng tương thích
- Thiết kế cốt lõi dùng mô hình dựa trên các đoạn thay đổi thay cho steps, kết hợp các kiểu node/mark độc lập với hệ thống mở rộng facet kiểu CodeMirror
- Giảm phụ thuộc vào hành vi chọn của trình duyệt bằng cách tự xử lý lựa chọn bằng con trỏ và bàn phím, nhưng vẫn giữ triển khai của trình duyệt cho chọn trên cảm ứng vì vấn đề menu ngữ cảnh native
- Có thể cài qua npm với
wordgard; tài liệu và sổ tay tham chiếu cũng đã được công bố, nhưng dự kiến sẽ ở phiên bản 0.x một thời gian để tiếp nhận phản hồi và sửa lỗi
Bản chất và trạng thái phát hành của Wordgard
- Wordgard là một dự án lặp lại mới của hệ thống trình soạn thảo văn bản giàu định dạng theo phong cách ProseMirror
- Dự án chịu nhiều ảnh hưởng từ những điều học được trong 9 năm kể từ khi ProseMirror ổn định và từ lần thiết kế lại CodeMirror phiên bản 6
- Đây là thư viện JavaScript hiển thị giao diện trình soạn thảo bằng DOM của trình duyệt, với giấy phép MIT
- Mã nguồn được công khai trên máy chủ Forgejo
- Có thể cài từ npm registry với
wordgard, và cách sử dụng có trên website
Vì sao tạo hệ thống mới thay vì thay đổi ProseMirror
- ProseMirror vẫn tiếp tục được bảo trì, nhưng một số thiết kế vẫn là những phần mà theo tiêu chuẩn hiện nay đáng lẽ nên làm khác đi
- Nếu phát hành ProseMirror 2.0 với giao diện không tương thích, khi mọi người nói “ProseMirror” sẽ dễ mơ hồ không biết đang chỉ điều gì
- Nếu gắn các ý tưởng mới vào ProseMirror 1.x theo cách tương thích ngược, cấu trúc có thể trở nên thỏa hiệp
- Wordgard lấy nhiều ý tưởng từ ProseMirror, nhưng giao diện lập trình được thiết kế lại từ đầu mà không xét đến tương thích
Biểu diễn thay đổi: mô hình dựa trên section thay cho steps
- Steps của ProseMirror chia thay đổi thành nhiều thao tác nguyên tử, trong đó mỗi step được áp dụng lên tài liệu được tạo bởi step trước đó
- Cách này hoạt động, nhưng việc hiệu chỉnh vị trí và theo dõi phạm vi thay đổi qua nhiều step khá phức tạp và khó xử lý
- Wordgard dùng một mô hình đơn giản hơn dựa trên cách biểu diễn thay đổi của CodeMirror và định dạng “delta” của ShareJS
- Nếu tài liệu có độ dài 10 và chèn
Ltại vị trí 4, nó được biểu diễn là[keep 4] [replace 0 with "L"] [keep 6] - Nếu xóa hai ký tự đầu tiên, nó được biểu diễn là
[replace 2 with ""] [keep 8]
- Nếu tài liệu có độ dài 10 và chèn
- Để xử lý rich text, hệ thống thêm các section thay đổi, cho phép thêm hoặc xóa các mark như nhấn mạnh, kiểu liên kết, văn bản thay thế của ảnh trong khi vẫn giữ cấu trúc
- Nếu làm đậm các từ từ vị trí 3 đến 6, nó được biểu diễn là
[keep 3] [update 3 +bold] [keep 4]
- Nếu làm đậm các từ từ vị trí 3 đến 6, nó được biểu diễn là
- Wordgard dùng chỉ mục đếm token giống ProseMirror để xử lý vị trí trong tài liệu như một chuỗi phẳng gồm các token mở/đóng node và token lá
- Một transaction đơn luôn có đúng một thay đổi, nên việc hợp thành thay đổi, kiểm tra và suy luận trở nên dễ hơn
- Hỗ trợ operational transform ở mức hạn chế để có thể hợp nhất nhiều thay đổi được biểu diễn dựa trên cùng một tài liệu khởi đầu
- Có thể biểu diễn thuận tiện hơn các transaction có nhiều thay đổi
- Có thể dùng cho biên tập cộng tác và triển khai undo history chỉ hoàn tác một số thay đổi
Cách duy trì cấu trúc tài liệu hợp lệ
- Tài liệu Wordgard không phải là một chuỗi token đơn giản, mà phải là một cấu trúc cây cân bằng
- Ví dụ, nếu xóa token đóng node, cân bằng token sẽ bị phá vỡ và có thể tạo ra thay đổi không áp dụng được
- Mã tạo tập thay đổi phải kiểm tra và hiệu chỉnh thay đổi để kết quả là cấu trúc tài liệu hợp lệ
- Trong operational transform, thay đổi sau khi transform cũng không được làm tài liệu trở nên vô hiệu
- Mô hình thay đổi của Wordgard suy ra một fix-up change để hiệu chỉnh kết quả kết hợp trong quá trình transform
- Sử dụng đầu vào cẩn thận để tạo cùng một hiệu chỉnh cho A-over-B và B-over-A
- Nếu không có hiệu chỉnh, hai thứ tự có thể tạo ra cùng một tài liệu nhưng có thể không hợp lệ
- Khi hợp thành cùng một hiệu chỉnh, cả hai thứ tự đều hội tụ về cùng một tài liệu hợp lệ
- Hầu hết thay đổi không cần hiệu chỉnh, nhưng kể cả khi cần, thiết kế vẫn duy trì tính hội tụ
Kết hợp schema và khái quát hóa mark
- Schema tài liệu của ProseMirror chỉ định trực tiếp quan hệ giữa các node, nên thường phải thiết lập thủ công
- Các kiểu node và mark của ProseMirror chỉ tồn tại bên trong một schema cụ thể, không có danh tính node có thể chia sẻ giữa các schema
- Trong Wordgard, kiểu node và mark là các đối tượng độc lập và có thể được đưa vào nhiều schema tài liệu
- Các đối tượng này hoạt động như những handle hỗ trợ định kiểu và tự động hoàn thành, giúp dễ tạo schema bằng cách kết hợp các thành phần cần thiết
- Schema có thể override quan hệ của các phần tử hiện có
- Định nghĩa node hoặc mark chỉ định nội dung mặc định hoặc kiểu đích
- Khi muốn dùng cùng một phần tử theo cách khác, schema có thể thay đổi quan hệ đó
- Có thể cung cấp phong phú hơn các node tích hợp sẵn mặc định, giúp dễ gắn trực tiếp vào node đó các tích hợp hệ thống như mở rộng hỗ trợ biên tập hoặc nút menu
- Những chức năng từng bị gắn với thuộc tính node cụ thể, như căn chỉnh văn bản hoặc văn bản thay thế, có thể được thêm theo cách module hóa hơn thông qua khái quát hóa mark
- Bản thân kiểu node không cần biết mark nào nhắm đến nó
Vì sao nới lỏng ràng buộc nội dung
- Tính năng tiêu biểu của ProseMirror là chỉ định nội dung được phép dựa trên biểu thức chính quy, nhưng Wordgard không hỗ trợ điều này
- Mô tả nội dung node của Wordgard chỉ giới hạn những kiểu con nào được hỗ trợ, chứ không giới hạn thứ tự của chúng
- Ràng buộc dựa trên biểu thức chính quy khiến việc viết mã thao tác tài liệu tổng quát trở nên khó khăn
- Mã không được viết riêng cho một schema cụ thể gần như không thể giả định phép biến đổi nào là hợp lệ
- Mọi thao tác đều phải được đối chiếu với ràng buộc nội dung, và quá trình này tinh tế nhưng nặng nề
- Các ràng buộc khóa chặt hình dạng tài liệu có thể ngăn những bước chỉnh sửa trung gian trên đường đến hình dạng mà người dùng muốn, làm hại trải nghiệm người dùng
- Wordgard khuyến khích cách tiếp cận hình dạng tài liệu lỏng hơn
- Khi cần các điều kiện bất biến vượt ngoài quy tắc schema, hệ thống cung cấp trừu tượng correction
- Hiệu chỉnh bằng chương trình những hình dạng tài liệu không muốn cho phép
- Cho phép hiệu chỉnh thông minh hơn và có xét đến ngữ cảnh hơn so với ép buộc bằng biểu thức nội dung
- Cũng có thể dùng cho các điều kiện như đảm bảo bảng hình chữ nhật, điều mà ràng buộc của ProseMirror cũng không biểu diễn được
Hệ thống mở rộng: facet kiểu CodeMirror 6
- Hệ thống mở rộng của ProseMirror là kiểu plugin đảm nhiệm nhiều việc, trong đó thứ tự mảng ảnh hưởng đến độ ưu tiên
- Có thể xuất hiện tình huống một plugin cần độ ưu tiên thấp ở một hook nhưng lại cần độ ưu tiên cao ở hook khác
- Hệ thống dựa trên facets của CodeMirror làm cho extension chi tiết hơn và cho phép từng giá trị extension đặt danh mục ưu tiên riêng
- Facet là một điểm mở rộng có kiểu, có thể được định nghĩa không chỉ bởi chính thư viện mà bởi bất kỳ mã nào
- Wordgard gần như mang nguyên hệ thống của CodeMirror vào phần này, bao gồm cả cơ chế cập nhật trạng thái và tái cấu hình
- Cấu hình không phải là mảng plugin mà là cây extension
- Định nghĩa event handler
- Thiết lập thuộc tính trình soạn thảo
- Thêm trạng thái trình soạn thảo mới
- Việc triển khai tính năng thường được cấu thành từ các nhóm extension hoạt động cùng nhau
- Các phần tử nguyên thủy được thiết kế để hầu hết bundle extension chỉ cần đưa vào cấu hình là có thể kết hợp tốt
Giảm phụ thuộc vào trình duyệt và xử lý lựa chọn
- Nhiều vấn đề của ProseMirror liên quan đến cách phụ thuộc vào hành vi chọn native của trình duyệt
- Cách tiếp cận cũ là để trình duyệt xử lý di chuyển con trỏ trong văn bản hai chiều hoặc nội dung có kiểu lạ, rồi phản ánh kết quả đó vào mô hình lựa chọn riêng
- Trên thực tế, trình duyệt có thể không di chuyển con trỏ qua một số nội dung, không vẽ con trỏ, vẽ sai vị trí, hoặc có hành vi bất thường khi kéo chọn bằng chuột
- Wordgard tự xử lý gần như toàn bộ lựa chọn dựa trên con trỏ và bàn phím
- Triển khai xử lý văn bản hai chiều
- Tạo mô hình bố cục nội dung
- Tự vẽ con trỏ
- Chọn trên cảm ứng là ngoại lệ, vẫn dùng triển khai native
- Có vẻ nếu triển khai lại, menu ngữ cảnh native sẽ bị hỏng
- Trên điện thoại và máy tính bảng, khó thay thế menu ngữ cảnh
- Chọn trên cảm ứng có xu hướng ít hành vi lạ hơn so với chọn bằng bàn phím
Xử lý sự kiện nhập và loại bỏ theo dõi thay đổi DOM
- Trong 9 năm qua, hỗ trợ sự kiện biên tập của trình duyệt, đặc biệt là hỗ trợ
beforeinput, đã nhất quán hơn - Cần thử nghiệm trong môi trường sử dụng thực tế, nhưng Wordgard có vẻ có thể hoạt động mà không cần theo dõi thay đổi DOM và các thủ thuật phân tích nội dung thay đổi mà ProseMirror từng phụ thuộc
- Wordgard xử lý sự kiện
beforeinputcho mọi thứ ngoại trừ nhập văn bản composition - Cách này tránh được một nhóm vấn đề vốn đòi hỏi nhiều triển khai vòng tránh lộn xộn
Độ ổn định, kế hoạch phiên bản và giấy phép
- Wordgard đang ở trạng thái tiến xa hơn một chút so với các dự án trước đây tại thời điểm công bố
- Các giao diện cốt lõi hỗ trợ gần như toàn bộ tính năng mong muốn, và một số extension cũng đã được viết để kiểm chứng thiết kế có thực dụng hay không
- Tài liệu vẫn còn hơi thô, nhưng sổ tay tham chiếu đã hoàn chỉnh và có thể sử dụng
- Có thể nhiều vấn đề sẽ chưa lộ ra cho đến khi mọi người dùng nó cho công việc thực tế
- Có những tính năng muốn bổ sung trong tương lai, và kỳ vọng người khác cũng xem xét sau khi công bố
- Một số phần của giao diện công khai có thể cần được suy nghĩ lại khi có thêm hiểu biết
- Phiên bản đầu tiên là 0.1, và dự kiến sẽ ở nhánh 0.x một thời gian để thu thập phản hồi, sửa lỗi và làm mượt các phần còn thô
- Thời gian dự kiến ít nhất khoảng 1 năm
- Giấy phép là MIT, giống các dự án trước đây
- Dù đã cân nhắc giấy phép hạn chế hơn, tác giả chọn giấy phép permissive vì quan tâm hơn đến việc được sử dụng rộng rãi
Mô hình AI, sinh mã và chính sách pull request
- Mô hình ngôn ngữ không được dùng để tạo phần mềm này
- Vì mã JavaScript nằm trên web và tài liệu phải được công khai, tác giả cho rằng không có cách đáng tin cậy để ngăn mã và ý tưởng công khai đi vào các mô hình ngôn ngữ lớn
- Với Wordgard, dự án thử nghiệm việc không nhận pull request, khác với thông lệ mã nguồn mở tiêu chuẩn
- Quá trình review các thay đổi lớn và điều chỉnh để khớp kỳ vọng thường tốn nhiều công hơn so với tự triển khai
- Khi chi phí sinh mã giảm mạnh, mô hình người khác ném mã sang rồi maintainer phải review, bảo trì hoặc giải thích lý do từ chối trở nên kém hấp dẫn hơn
1 bình luận
Các ý kiến trên Lobste.rs
Với tư cách tác giả, tôi thỉnh thoảng sẽ kiểm tra luồng này nếu có câu hỏi hoặc phản hồi
Có lẽ có thể tạo HTML bằng một Markdown renderer rồi cho Wordgard chỉnh sửa, nhưng sau đó làm thế nào để trích xuất Markdown từ nội dung trong trình chỉnh sửa?
Cuối cùng họ có chuyển sang Wordgard không? Nếu có người định dùng ProseMirror cho một dự án mới, thì khi nào nên chọn Wordgard?
Và còn có phần artwork tuyệt đẹp do một nghệ sĩ con người thực thụ tạo ra
Hay đấy
Xin chúc mừng thật nhiều cho dự án và bài ra mắt của Marijn. Trông rất tuyệt, và tôi cũng thích artwork của Kamila Stankiewicz
Trang chủ chính của dự án là https://wordgard.net/
Phần này, đặc biệt là toàn bộ đoạn cuối, thật sự rất thú vị
Tôi cũng tự hỏi liệu cách làm như vậy có trở nên phổ biến hơn trong một thời gian không, cho đến khi chúng ta xây dựng được mối quan hệ tốt hơn với sinh mã bằng AI, hoặc đi theo hướng hoàn toàn không có mối quan hệ nào với nó
Nhân tiện, mã nguồn dùng giấy phép MIT