             @nb.dirty = false
 
     sync: () =>
+        if @readonly
+            return
         @save_button.icon_spin(start:true,delay:1000)
         @doc.sync () =>
             @save_button.icon_spin(false)

                            @reload() # -- only thing we can do, really

    autosync: () =>
        @check_for_moved_server()  # only bother if document being changed.
        if @frame?.IPython?.notebook?.dirty and not @_reloading
            #console.log("causing sync")

                            @nb._save_checkpoint = @nb.save_checkpoint
                            @nb.save_checkpoint = @save

                            if @readonly
                                @frame.$("#save_widget").append($("<b style='background: red;color: white;padding-left: 1ex; padding-right: 1ex;'>This is a READONLY document that can't be saved.</b>"))

                            # Ipython doesn't consider a load (e.g., snapshot restore) "dirty" (for obvious reasons!)
                            @nb._load_notebook_success = @nb.load_notebook_success
                            @nb.load_notebook_success = (data,status,xhr) =>
