javascript - 如何使用 Google Drive Realtime API 实现协作富文本编辑?

标签 javascript google-drive-api data-modeling rich-text-editor google-drive-realtime-api

我正在开发一个使用 Google Drive Realtime API 的网络应用程序. API 用于存储文档数据并同步事件协作者之间的所有修改。

现在我想为这个应用程序添加对富文本文本框的支持(只有粗体、下划线和链接等基本内容)。文本框应启用类似于 Google Docs 的协作文本编辑.我已经搜索和试验了几天,但我找不到关于如何交换数据或如何构建适用于 Drive Realtime API 的合适数据模型的合适解决方案。

人们可以想到多种方式,比如在 CollaborativeSting 中交换 HTML(或类似的标记)。 .但这行不通,因为它迟早会破坏标记。

另一个(可能更好)起点是使用更多 abstract data model作为 Quill editor does . (如果可能的话,我想稍后使用这个编辑器,但这不是必须的。)

Hello! Here is a link.”的富文本模型如下所示:

var doc = [
    { insert: "Hello!", attributes: { bold: true } },
    { insert: " Here is a " },
    { insert: "link.", attributes: { href: 'http://example.org' } }
];

我可以使用以下说明将上面的文档示例转换为“Hello! 那是 link. ”:

var operation = [
    { retain: 7 },
    { insert: "That's", attributes: { italic: true } },
    { delete: 1 }
];

但是,如果更多协作者同时输入或格式化,则将此模型保存到 CollaborativeList 中似乎也不是解决方案。特别是因为我无法影响服务器端的行为。

有人能想出适合富文本的模型或数据交换过程吗?它不一定是最佳解决方案(如果介于两者之间)。使用此 API 交换纯文本非常简单,但富文本对我来说似乎是不可能的。

感谢您的帮助!


更新

我可以用新信息精确地回答我的问题 Sheryl Simon provided me below .通过使用 IndexReferences,我现在能够将纯文本与格式信息隔离开来。

我添加了一些代码来保存用户的本地文本选择(可以是单个位置或范围)并在文本更改后恢复它。这很好用。我还可以添加对单个用户的多个文本选择的支持 - 因为每个用户只能更改自己的选择。

但我想不出一个模型,其中多个用户可以同时添加和删除范围,例如加粗字体。如果我将 CollaborativeList 用于其中包含多个 [start, end] 数组的粗体文本,如果两个用户同时设置重叠范围或者两个用户想要,我将得到一个损坏的数据集同时编辑同一范围(通过删除和重新插入范围或移动现有范围的范围标记)。

以下是一些伪代码。所有索引都存储为 IndexReferences:

Model:           
[                User1: makeBold([8,20])
    [ 0, 10]     => removeValue([0,10]), removeValue([15,36]), push([0,36])
    [15, 36]       
    [77, 82]     User2: removeBold([0,5])
]                => removeValue([0,10]), push([6,10])

如果两个用户都从左侧显示的数据集开始,并且第一个用户的操作首先应用,则第二个用户无法再删除 [0,10](因为它已被替换)所以文本保持粗体并将 [6,10] 插入列表会导致重复数据。我怎样才能避免这些问题?

最佳答案

查看 IndexReferences。这就是那些设计的目的。您基本上跟踪区域开始和结束的标记,该标记应该是粗体、斜体等。如果在区域之前或区域内添加文本,IndexReference 将自动四处移动,因此它应该表现得合乎逻辑。

关于javascript - 如何使用 Google Drive Realtime API 实现协作富文本编辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27761200/

相关文章:

android - 如何将我的 SQLITE 数据库保存到 Google 云端硬盘?

cassandra - 如何仅在属性未更改时有条件地将数据保存在 cassandra 中

javascript - 如何在React中使用 'THIS'的2个不同值

javascript - Chrome 扩展程序中的功能无法运行

google-api - 撤消授予我的应用 Google Drive API 的访问权限

python - 基本数据模型模式的 Django 多表继承替代方案

search - Amazon Cloud Search - 按时间和日期获取地点

javascript - 我可以使用 Javascript 检测 XHTML 解析错误吗?

javascript - 使用主干 View 引用窗口变量

javascript - Google Apps 脚本 "ExecutionResponse"对象不包含 "result"