瀏覽代碼

Add the carets as an absolutely positioned element so that they can
float across boundaries.

Ian Rose 8 年之前
父節點
當前提交
89673c5e2d
共有 2 個文件被更改,包括 23 次插入6 次删除
  1. 21 5
      packages/codemirror/src/editor.ts
  2. 2 1
      packages/codemirror/style/index.css

+ 21 - 5
packages/codemirror/src/editor.ts

@@ -544,6 +544,11 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
       markers.forEach(marker => { marker.clear(); });
     }
     delete this.selectionMarkers[uuid];
+    const carets = this.caretMarkers[uuid];
+    if (carets) {
+      carets.forEach(caret => { document.body.removeChild(caret); });
+    }
+    delete this.caretMarkers[uuid];
   }
 
   /**
@@ -551,10 +556,16 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
    */
   private _markSelections(uuid: string, selections: CodeEditor.ITextSelection[]) {
     const markers: CodeMirror.TextMarker[] = [];
+    const carets: HTMLElement[] = [];
+
+    // If we can id the selection to a specific collaborator,
+    // use that information.
     let collaborator: ICollaborator;
-    if (this._model.modelDB.isCollaborative) {
+    if (this._model.modelDB.collaborators) {
       collaborator = this._model.modelDB.collaborators.get(uuid);
     }
+
+    // Style each selection for the uuid.
     selections.forEach(selection => {
       // Only render selections if the start is not equal to the end.
       // In that case, we don't need to render the cursor.
@@ -563,12 +574,13 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
         const markerOptions = this._toTextMarkerOptions(selection.style);
         markers.push(this.doc.markText(anchor, head, markerOptions));
       } else {
-        let caret = this._getCaret(collaborator);
-        markers.push(this.doc.setBookmark(
-          this._toCodeMirrorPosition(selection.end), {widget: caret}));
+        let caret = this._getCaret(selection.end, collaborator);
+        document.body.appendChild(caret);
+        carets.push(caret);
       }
     });
     this.selectionMarkers[uuid] = markers;
+    this.caretMarkers[uuid] = carets;
   }
 
   /**
@@ -747,7 +759,7 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
    * Construct a caret element representing the position
    * of a collaborator's cursor.
    */
-  private _getCaret(collaborator: ICollaborator): HTMLElement {
+  private _getCaret(position: CodeEditor.IPosition, collaborator: ICollaborator): HTMLElement {
     let name = collaborator ? collaborator.displayName : 'Anonymous';
     let color = collaborator ? collaborator.color : this._selectionStyle.color;
     let caret: HTMLElement = document.createElement('span');
@@ -755,12 +767,16 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
     caret.className = `jp-CollaboratorCursor`;
     caret.style.backgroundColor = color; // Allows inheritence in :after element.
     caret.style.borderBottomColor = color;
+    let coordinates = this.getCoordinateForPosition(position);
+    caret.style.top = `${coordinates.bottom}px`;
+    caret.style.left = `${coordinates.left}px`;
     return caret;
   }
 
   private _model: CodeEditor.IModel;
   private _editor: CodeMirror.Editor;
   protected selectionMarkers: { [key: string]: CodeMirror.TextMarker[] | undefined } = {};
+  protected caretMarkers: { [key: string]: HTMLElement[] | undefined } = {};
   private _keydownHandlers = new Array<CodeEditor.KeydownHandler>();
   private _changeGuard = false;
   private _selectionStyle: CodeEditor.ISelectionStyle;

+ 2 - 1
packages/codemirror/style/index.css

@@ -67,6 +67,7 @@
 }
 
 .jp-CollaboratorCursor {
+  position: absolute;
   border-left: 5px solid transparent;
   border-right: 5px solid transparent;
   border-top: none;
@@ -80,7 +81,7 @@
   content: attr(data-name);
   position: absolute;
   z-index: 1;
-  transform: translateX(-50%) translateY(100%);
+  transform: translateX(-50%) translateY(3px);
   background-color: inherit;
   color: white;
   border-radius: 3px;