Commit 82a0168e authored by Ayush's avatar Ayush

Optimize imports and code

parent b3aed7ac
import { TestBed } from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import { ApiService } from './api.service'; import {ApiService} from './api.service';
describe('ApiService', () => { describe('ApiService', () => {
let service: ApiService; let service: ApiService;
......
import { NgModule } from '@angular/core'; import {NgModule} from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import {RouterModule, Routes} from '@angular/router';
import { HomeComponent } from './home/home.component'; import {HomeComponent} from './home/home.component';
import { ArenaComponent } from './arena/arena.component'; import {ArenaComponent} from './arena/arena.component';
import { UserComponent } from './user/user.component'; import {UserComponent} from './user/user.component';
import { IdeComponent } from './ide/ide.component'; import {IdeComponent} from './ide/ide.component';
import { LoginComponent } from './login/login.component'; import {LoginComponent} from './login/login.component';
import { RegisterComponent } from './register/register.component'; import {RegisterComponent} from './register/register.component';
import { AuthGuard } from './auth.guard'; import {AuthGuard} from './auth.guard';
import { FileComponent } from './file/file.component'; import {FileComponent} from './file/file.component';
const routes: Routes = [ const routes: Routes = [
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] }, {path: 'home', component: HomeComponent, canActivate: [AuthGuard]},
{ path: 'arena/problem/:id', component: ArenaComponent, canActivate: [AuthGuard] }, {path: 'arena/problem/:id', component: ArenaComponent, canActivate: [AuthGuard]},
{ path: 'arena/file/:id', component: IdeComponent, canActivate: [AuthGuard] }, {path: 'arena/file/:id', component: IdeComponent, canActivate: [AuthGuard]},
{ path: 'arena/file/new', component: IdeComponent, canActivate: [AuthGuard] }, {path: 'arena/file/new', component: IdeComponent, canActivate: [AuthGuard]},
{ path: 'user', component: UserComponent, canActivate: [AuthGuard] }, {path: 'user', component: UserComponent, canActivate: [AuthGuard]},
{ path: 'files', component: FileComponent, canActivate: [AuthGuard] }, {path: 'files', component: FileComponent, canActivate: [AuthGuard]},
{ path: 'login', component: LoginComponent }, {path: 'login', component: LoginComponent},
{ path: 'register', component: RegisterComponent }, {path: 'register', component: RegisterComponent},
{ path: '**', redirectTo: '/home' }, {path: '**', redirectTo: '/home'},
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes)], imports: [RouterModule.forRoot(routes)],
exports: [RouterModule] exports: [RouterModule]
}) })
export class AppRoutingModule { } export class AppRoutingModule {
}
export var routerComponents = [ export var routerComponents = [
HomeComponent, HomeComponent,
......
import { TestBed } from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; import {RouterTestingModule} from '@angular/router/testing';
import { AppComponent } from './app.component'; import {AppComponent} from './app.component';
describe('AppComponent', () => { describe('AppComponent', () => {
beforeEach(async () => { beforeEach(async () => {
......
import { Component } from '@angular/core'; import {Component} from '@angular/core';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
......
import { BrowserModule } from '@angular/platform-browser'; import {BrowserModule} from '@angular/platform-browser';
import { NgModule } from '@angular/core'; import {CUSTOM_ELEMENTS_SCHEMA, NgModule} from '@angular/core';
import { AppRoutingModule } from './app-routing.module'; import {AppRoutingModule, routerComponents} from './app-routing.module';
import { routerComponents } from './app-routing.module'; import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import {HttpClientModule} from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http'; import {AppComponent} from './app.component';
import { AppComponent } from './app.component'; import {HeaderComponent} from './header/header.component';
import { HeaderComponent } from './header/header.component'; import {ApiService} from './api.service';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import {IdeCompileComponent} from './ide-compile/ide-compile.component';
import { ApiService } from './api.service'; import {InputComponent} from './input/input.component';
import { IdeCompileComponent } from './ide-compile/ide-compile.component'; import {TestcaseStatusComponent} from './testcase-status/testcase-status.component';
import { InputComponent } from './input/input.component'; import {SaveFileComponent} from './save-file/save-file.component';
import { TestcaseStatusComponent } from './testcase-status/testcase-status.component'; import {FileComponent} from './file/file.component';
import { SaveFileComponent } from './save-file/save-file.component'; import {FileService} from './file.service';
import { FileComponent } from './file/file.component';
import { FileService } from './file.service';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -38,4 +36,5 @@ import { FileService } from './file.service'; ...@@ -38,4 +36,5 @@ import { FileService } from './file.service';
bootstrap: [AppComponent], bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}) })
export class AppModule { } export class AppModule {
}
<div class="container"> <div class="container">
<div class="card" id="ps" [innerHTML]="problem.problem_statement"> <div [innerHTML]="problem.problem_statement" class="card" id="ps">
</div> </div>
<div id="toggle-lang">C++</div> <div id="toggle-lang">C++</div>
<div id="attempt"> <div id="attempt">
...@@ -8,5 +8,6 @@ ...@@ -8,5 +8,6 @@
<button id="submit">Submit Code</button> <button id="submit">Submit Code</button>
</div> </div>
<label for="editor"></label> <label for="editor"></label>
<textarea name="editor" id="editor"></textarea> <textarea id="editor" name="editor"></textarea>
</div> </div>
<app-input></app-input>
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { ArenaComponent } from './arena.component'; import {ArenaComponent} from './arena.component';
describe('ArenaComponent', () => { describe('ArenaComponent', () => {
let component: ArenaComponent; let component: ArenaComponent;
...@@ -8,9 +8,9 @@ describe('ArenaComponent', () => { ...@@ -8,9 +8,9 @@ describe('ArenaComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ ArenaComponent ] declarations: [ArenaComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
...@@ -2,6 +2,8 @@ import {Component, OnInit} from '@angular/core'; ...@@ -2,6 +2,8 @@ import {Component, OnInit} from '@angular/core';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {Problem} from '../problem'; import {Problem} from '../problem';
import {ProblemService} from '../problem.service'; import {ProblemService} from '../problem.service';
import {File} from '../file';
import {ApiService} from '../api.service';
declare const CodeMirror: any; declare const CodeMirror: any;
...@@ -14,8 +16,9 @@ export class ArenaComponent implements OnInit { ...@@ -14,8 +16,9 @@ export class ArenaComponent implements OnInit {
id: number; id: number;
problem: Problem; problem: Problem;
files: File[] = [];
constructor(public router: Router, private problemService: ProblemService) { constructor(public router: Router, private problemService: ProblemService, private apiService: ApiService) {
} }
ngOnInit(): void { ngOnInit(): void {
...@@ -34,11 +37,12 @@ export class ArenaComponent implements OnInit { ...@@ -34,11 +37,12 @@ export class ArenaComponent implements OnInit {
Object.assign((document.getElementsByClassName('CodeMirror')[0] as HTMLTextAreaElement).style, { Object.assign((document.getElementsByClassName('CodeMirror')[0] as HTMLTextAreaElement).style, {
borderBottom: '1px solid #ddf', borderBottom: '1px solid #ddf',
padding: '20px', padding: '20px',
fontFamily: '"Space Mono", monospace', fontFamily: '"Anonymous Pro", monospace',
}); });
let activeLang = 0; let activeLang = 0;
const langs = ['C++', 'Python', 'Java']; const langs = ['C++', 'Python', 'Java'];
const extensions = ['.cpp', '.py', '.java'];
const langsMime = ['text/x-c++src', 'text/x-python', 'text/x-java']; const langsMime = ['text/x-c++src', 'text/x-python', 'text/x-java'];
const problem = this.problem; const problem = this.problem;
...@@ -51,6 +55,18 @@ export class ArenaComponent implements OnInit { ...@@ -51,6 +55,18 @@ export class ArenaComponent implements OnInit {
editor.setOption('mode', langsMime[activeLang]); editor.setOption('mode', langsMime[activeLang]);
}; };
const filename = this.id.toString(10);
const username = JSON.parse(this.apiService.getToken()).username;
for (const ext of extensions) {
this.files.push({
id: null,
username,
filename,
language: ext,
text: ''
});
}
} }
getProblem(): void { getProblem(): void {
......
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, CanActivate, Router } from '@angular/router'; import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import { ApiService } from './api.service'; import {ApiService} from './api.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private dataService: ApiService, private router: Router) { } constructor(private dataService: ApiService, private router: Router) {
canActivate( }
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot canActivate(
): boolean { route: ActivatedRouteSnapshot,
const routeUrl: string = state.url; state: RouterStateSnapshot
return this.isLogin(routeUrl); ): boolean {
} const routeUrl: string = state.url;
return this.isLogin(routeUrl);
}
isLogin(routeUrl: string) { isLogin(routeUrl: string) {
if (this.dataService.isLoggedIn()) { if (this.dataService.isLoggedIn()) {
return true; return true;
}
this.dataService.redirectUrl = routeUrl;
this.router.navigate(['/login'], { queryParams: { returnUrl: routeUrl } });
} }
} this.dataService.redirectUrl = routeUrl;
\ No newline at end of file this.router.navigate(['/login'], {queryParams: {returnUrl: routeUrl}});
}
}
import { TestBed } from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import { FileService } from './file.service'; import {FileService} from './file.service';
describe('FileService', () => { describe('FileService', () => {
let service: FileService; let service: FileService;
......
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
import { File } from './file'; import {File} from './file';
import { Observable, of } from 'rxjs'; import {Observable, of} from 'rxjs';
import { HttpClient } from '@angular/common/http'; import {HttpClient} from '@angular/common/http';
@Injectable({ @Injectable({
...@@ -11,7 +11,8 @@ export class FileService { ...@@ -11,7 +11,8 @@ export class FileService {
baseApiUrl = 'https://file.io'; baseApiUrl = 'https://file.io';
constructor(private http: HttpClient) { } constructor(private http: HttpClient) {
}
getFiles(): Observable<File[]> { getFiles(): Observable<File[]> {
......
export interface File { export interface File {
id: number; id: number;
username: string; username: string;
filename: string; filename: string;
language: string; language: string;
text: string; text: string;
} }
...@@ -52,13 +52,13 @@ ...@@ -52,13 +52,13 @@
<div [class.open]="uploadPopupActive" id="file-upload-popup"> <div [class.open]="uploadPopupActive" id="file-upload-popup">
<p>Upload a file:</p> <p>Upload a file:</p>
<input id="file-upload-input" type="file" (change)="onChange($event)"> <input (change)="onChange($event)" id="file-upload-input" type="file">
<div style="margin-top: 10px" *ngIf="shortLink !== ''"> <div *ngIf="shortLink !== ''" style="margin-top: 10px">
<a target="_blank" href="{{shortLink}}">Link to last upload</a> <a href="{{shortLink}}" target="_blank">Link to last upload</a>
</div> </div>
<p *ngIf="!loading"> <p *ngIf="!loading">
<button id="upload-cancel-btn" (click)="uploadPopupActive = false;">Close</button> <button (click)="uploadPopupActive = false;" id="upload-cancel-btn">Close</button>
<button id="file-upload-btn" (click)="onUpload()">Upload</button> <button (click)="onUpload()" id="file-upload-btn">Upload</button>
</p> </p>
<p *ngIf="loading" style="margin-top: 20px; text-align: center"> <p *ngIf="loading" style="margin-top: 20px; text-align: center">
Uploading... Uploading...
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
button { button {
float: right; float: right;
border:none; border: none;
} }
.title { .title {
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { FileComponent } from './file.component'; import {FileComponent} from './file.component';
describe('FileComponent', () => { describe('FileComponent', () => {
let component: FileComponent; let component: FileComponent;
...@@ -8,9 +8,9 @@ describe('FileComponent', () => { ...@@ -8,9 +8,9 @@ describe('FileComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ FileComponent ] declarations: [FileComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { HeaderComponent } from './header.component'; import {HeaderComponent} from './header.component';
describe('HeaderComponent', () => { describe('HeaderComponent', () => {
let component: HeaderComponent; let component: HeaderComponent;
...@@ -8,9 +8,9 @@ describe('HeaderComponent', () => { ...@@ -8,9 +8,9 @@ describe('HeaderComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ HeaderComponent ] declarations: [HeaderComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { Component, OnInit } from '@angular/core'; import {Component, OnInit} from '@angular/core';
import { ApiService } from '../api.service'; import {ApiService} from '../api.service';
@Component({ @Component({
selector: 'app-header', selector: 'app-header',
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { HomeComponent } from './home.component'; import {HomeComponent} from './home.component';
describe('HomeComponent', () => { describe('HomeComponent', () => {
let component: HomeComponent; let component: HomeComponent;
...@@ -8,9 +8,9 @@ describe('HomeComponent', () => { ...@@ -8,9 +8,9 @@ describe('HomeComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ HomeComponent ] declarations: [HomeComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { Component, OnInit } from '@angular/core'; import {Component, OnInit} from '@angular/core';
import { ProblemService } from '../problem.service'; import {ProblemService} from '../problem.service';
import { Problem } from '../problem'; import {Problem} from '../problem';
@Component({ @Component({
selector: 'app-home', selector: 'app-home',
...@@ -9,9 +9,11 @@ import { Problem } from '../problem'; ...@@ -9,9 +9,11 @@ import { Problem } from '../problem';
}) })
export class HomeComponent implements OnInit { export class HomeComponent implements OnInit {
constructor(private problemService: ProblemService) { }
problems: Problem[]; problems: Problem[];
constructor(private problemService: ProblemService) {
}
ngOnInit(): void { ngOnInit(): void {
this.getProblems(); this.getProblems();
} }
......
<div id="compile-cover" [class.open]="isActive"></div> <div [class.open]="isActive" id="compile-cover"></div>
<div id="compile-popup" [class.open]="isActive"> <div [class.open]="isActive" id="compile-popup">
<p id="compile-status" [innerHTML]="statusVal"></p> <p [innerHTML]="statusVal" id="compile-status"></p>
<button id="compile-done" [class.disabled]="resultVal === 0" (click)="resultVal !== 0 && setState(false)">Done</button> <button (click)="resultVal !== 0 && setState(false)" [class.disabled]="resultVal === 0" id="compile-done">Done
</button>
</div> </div>
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { IdeCompileComponent } from './ide-compile.component'; import {IdeCompileComponent} from './ide-compile.component';
describe('IdeCompileComponent', () => { describe('IdeCompileComponent', () => {
let component: IdeCompileComponent; let component: IdeCompileComponent;
...@@ -8,9 +8,9 @@ describe('IdeCompileComponent', () => { ...@@ -8,9 +8,9 @@ describe('IdeCompileComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ IdeCompileComponent ] declarations: [IdeCompileComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { Component, OnInit, Input } from '@angular/core'; import {Component, Input, OnInit} from '@angular/core';
@Component({ @Component({
selector: 'app-ide-compile', selector: 'app-ide-compile',
...@@ -9,15 +9,18 @@ export class IdeCompileComponent implements OnInit { ...@@ -9,15 +9,18 @@ export class IdeCompileComponent implements OnInit {
@Input() statusVal: string; @Input() statusVal: string;
@Input() resultVal: number; @Input() resultVal: number;
isActive = false; isActive = false;
constructor() { }
ngOnInit(): void { } constructor() {
setState(inp: boolean): void {
this.isActive = inp;
} }
set status(value: string) { set status(value: string) {
this.statusVal = value; this.statusVal = value;
} }
ngOnInit(): void {
}
setState(inp: boolean): void {
this.isActive = inp;
}
} }
...@@ -3,13 +3,15 @@ ...@@ -3,13 +3,15 @@
<div id="attempt"> <div id="attempt">
<span *ngIf="!isUpToDate"></span> <span *ngIf="!isUpToDate"></span>
<span id="ideFileName">{{file.filename + file.language}}</span> <span id="ideFileName">{{file.filename + file.language}}</span>
<button id="inputBtn" (click)="inputField.setState(true);">Input</button> <button (click)="inputField.setState(true);" id="inputBtn">Input</button>
<button id="runBtn" (click)="this.runField.isActive = true; this.runCodeService.run()">Run Code</button> <button (click)="this.runField.isActive = true; this.runCodeService.run()" id="runBtn">Run Code</button>
<button id="saveBtn" (click)="!isSaved ? this.saveField.setState(true) : updateFile();" [class.disabled]="isUploading || isUpToDate">{{isUploading ? "Saving File..." : "Save File"}}</button> <button (click)="!isSaved ? this.saveField.setState(true) : updateFile();"
[class.disabled]="isUploading || isUpToDate"
id="saveBtn">{{isUploading ? "Saving File..." : "Save File"}}</button>
</div> </div>
<label for="editor"></label> <label for="editor"></label>
<textarea name="editor" id="editor" value="{{inp}}"></textarea> <textarea id="editor" name="editor" value="{{inp}}"></textarea>
</div> </div>
<app-input (valueEmit)="updateInput($event)"></app-input> <app-input (valueEmit)="updateInput($event)"></app-input>
<app-ide-compile [statusVal]="runCodeService.status" [resultVal]="runCodeService.result"></app-ide-compile> <app-ide-compile [resultVal]="runCodeService.result" [statusVal]="runCodeService.status"></app-ide-compile>
<app-save-file [file]="file" (savedFile)="isSaved = isUpToDate = true;"></app-save-file> <app-save-file (savedFile)="isSaved = isUpToDate = true;" [file]="file"></app-save-file>
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { IdeComponent } from './ide.component'; import {IdeComponent} from './ide.component';
describe('IdeComponent', () => { describe('IdeComponent', () => {
let component: IdeComponent; let component: IdeComponent;
...@@ -8,9 +8,9 @@ describe('IdeComponent', () => { ...@@ -8,9 +8,9 @@ describe('IdeComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ IdeComponent ] declarations: [IdeComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
...@@ -50,7 +50,7 @@ export class IdeComponent implements OnInit { ...@@ -50,7 +50,7 @@ export class IdeComponent implements OnInit {
Object.assign((document.getElementsByClassName('CodeMirror')[0] as HTMLTextAreaElement).style, { Object.assign((document.getElementsByClassName('CodeMirror')[0] as HTMLTextAreaElement).style, {
borderBottom: '1px solid #ddf', borderBottom: '1px solid #ddf',
padding: '20px', padding: '20px',
fontFamily: '"Space Mono", monospace', fontFamily: '"Anonymous Pro", monospace',
}); });
let activeLang = 0; let activeLang = 0;
......
<div id="input-cover" [class.open]="isActive"></div> <div [class.open]="isActive" id="input-cover"></div>
<div id="input" [class.open]="isActive"> <div [class.open]="isActive" id="input">
<label for="inp" id="title">Enter the input:</label> <label for="inp" id="title">Enter the input:</label>
<br> <br>
<textarea name="inp" id="inp" cols="30" rows="10" spellcheck="false"></textarea> <textarea cols="30" id="inp" name="inp" rows="10" spellcheck="false"></textarea>
<br> <br>
<button id="done" (click)="this.setState(false);">Done</button> <button (click)="this.setState(false);" id="done">Done</button>
</div> </div>
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
font-size: 1.1em; font-size: 1.1em;
background: transparent; background: transparent;
border: none; border: none;
font-family: 'Space Mono', monospace; font-family: 'Anonymous Pro', monospace;
resize: none; resize: none;
} }
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { InputComponent } from './input.component'; import {InputComponent} from './input.component';
describe('InputComponent', () => { describe('InputComponent', () => {
let component: InputComponent; let component: InputComponent;
...@@ -8,9 +8,9 @@ describe('InputComponent', () => { ...@@ -8,9 +8,9 @@ describe('InputComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ InputComponent ] declarations: [InputComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { Component, OnInit, EventEmitter, Output } from '@angular/core'; import {Component, EventEmitter, OnInit, Output} from '@angular/core';
@Component({ @Component({
selector: 'app-input', selector: 'app-input',
...@@ -9,9 +9,12 @@ export class InputComponent implements OnInit { ...@@ -9,9 +9,12 @@ export class InputComponent implements OnInit {
isActive = false; isActive = false;
value: string; value: string;
@Output() valueEmit = new EventEmitter<string>(); @Output() valueEmit = new EventEmitter<string>();
constructor() { }
ngOnInit(): void { } constructor() {
}
ngOnInit(): void {
}
setState(value: boolean): void { setState(value: boolean): void {
const text = document.getElementById('inp') as HTMLTextAreaElement; const text = document.getElementById('inp') as HTMLTextAreaElement;
......
<form id="login_form" action="" [formGroup]="form" novalidate (ngSubmit)="postData(form)"> <form (ngSubmit)="postData(form)" [formGroup]="form" action="" id="login_form" novalidate>
<div class="form-row"> <div class="form-row">
<label for="username">Username</label> <label for="username">Username</label>
<input id="username" type="text" formControlName="username" spellcheck="false"> <input formControlName="username" id="username" spellcheck="false" type="text">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="password">Password</label> <label for="password">Password</label>
<input id="password" type="password" formControlName="password" spellcheck="false"> <input formControlName="password" id="password" spellcheck="false" type="password">
</div> </div>
<div class="form-row"> <div class="form-row">
<input id="submit" value="Submit" type="submit"> <input id="submit" type="submit" value="Submit">
</div> </div>
</form> </form>
...@@ -29,4 +29,4 @@ ...@@ -29,4 +29,4 @@
information. information.
</p> </p>
</div> </div>
</div> </div>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { LoginComponent } from './login.component'; import {LoginComponent} from './login.component';
describe('LoginComponent', () => { describe('LoginComponent', () => {
let component: LoginComponent; let component: LoginComponent;
...@@ -8,9 +8,9 @@ describe('LoginComponent', () => { ...@@ -8,9 +8,9 @@ describe('LoginComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ LoginComponent ] declarations: [LoginComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { TestBed } from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import { ProblemService } from './problem.service'; import {ProblemService} from './problem.service';
describe('ProblemService', () => { describe('ProblemService', () => {
let service: ProblemService; let service: ProblemService;
......
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
import { Problem } from './problem'; import {Problem} from './problem';
import { Observable, of } from 'rxjs'; import {Observable, of} from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ProblemService { export class ProblemService {
constructor() { } constructor() {
}
getProblems(): Observable<Problem[]> { getProblems(): Observable<Problem[]> {
......
<form id="login_form" action="" [formGroup]="form" (ngSubmit)="postData(form)"> <form (ngSubmit)="postData(form)" [formGroup]="form" action="" id="login_form">
<div class="form-row"> <div class="form-row">
<label for="name">Name</label> <label for="name">Name</label>
<input id="name" type="text" formControlName="name" spellcheck="false"> <input formControlName="name" id="name" spellcheck="false" type="text">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="username">Username</label> <label for="username">Username</label>
<input id="username" type="text" formControlName="username" spellcheck="false"> <input formControlName="username" id="username" spellcheck="false" type="text">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="email">Email</label> <label for="email">Email</label>
<input id="email" type="text" formControlName="email" spellcheck="false"> <input formControlName="email" id="email" spellcheck="false" type="text">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="password">Password</label> <label for="password">Password</label>
<input id="password" type="password" formControlName="password" spellcheck="false"> <input formControlName="password" id="password" spellcheck="false" type="password">
</div> </div>
<div class="form-row"> <div class="form-row">
<label for="confirm_password">Confirm Password</label> <label for="confirm_password">Confirm Password</label>
<input id="confirm_password" type="password" formControlName="confirm_password" spellcheck="false"> <input formControlName="confirm_password" id="confirm_password" spellcheck="false" type="password">
</div> </div>
<div class="form-row"> <div class="form-row">
<input id="submit" value="Submit" type="submit"> <input id="submit" type="submit" value="Submit">
</div> </div>
</form> </form>
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { RegisterComponent } from './register.component'; import {RegisterComponent} from './register.component';
describe('RegisterComponent', () => { describe('RegisterComponent', () => {
let component: RegisterComponent; let component: RegisterComponent;
...@@ -8,9 +8,9 @@ describe('RegisterComponent', () => { ...@@ -8,9 +8,9 @@ describe('RegisterComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ RegisterComponent ] declarations: [RegisterComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { Component, OnInit } from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import { first } from 'rxjs/operators'; import {first} from 'rxjs/operators';
import { ApiService } from '../api.service'; import {ApiService} from '../api.service';
@Component({ @Component({
selector: 'app-register', selector: 'app-register',
...@@ -11,6 +11,8 @@ import { ApiService } from '../api.service'; ...@@ -11,6 +11,8 @@ import { ApiService } from '../api.service';
export class RegisterComponent implements OnInit { export class RegisterComponent implements OnInit {
form: FormGroup; form: FormGroup;
timeout: any; timeout: any;
set: NodeListOf<HTMLInputElement>;
submitElement: HTMLInputElement;
constructor(private fb: FormBuilder, private dataService: ApiService) { constructor(private fb: FormBuilder, private dataService: ApiService) {
this.form = this.fb.group({ this.form = this.fb.group({
...@@ -22,8 +24,21 @@ export class RegisterComponent implements OnInit { ...@@ -22,8 +24,21 @@ export class RegisterComponent implements OnInit {
}); });
} }
set: NodeListOf<HTMLInputElement>; get email(): AbstractControl {
submitElement: HTMLInputElement; return this.form.get('email');
}
get password(): AbstractControl {
return this.form.get('password');
}
get name(): AbstractControl {
return this.form.get('name');
}
get username(): AbstractControl {
return this.form.get('name');
}
ngOnInit(): void { ngOnInit(): void {
this.submitElement = document.getElementById('submit') as HTMLInputElement; this.submitElement = document.getElementById('submit') as HTMLInputElement;
...@@ -44,8 +59,7 @@ export class RegisterComponent implements OnInit { ...@@ -44,8 +59,7 @@ export class RegisterComponent implements OnInit {
this.set.forEach(item => { this.set.forEach(item => {
if (item.value !== '' && item.value !== null) { if (item.value !== '' && item.value !== null) {
item.parentElement.querySelector('label').classList.add('active'); item.parentElement.querySelector('label').classList.add('active');
} } else {
else {
item.parentElement.querySelector('label').classList.remove('active'); item.parentElement.querySelector('label').classList.remove('active');
} }
}); });
...@@ -53,7 +67,9 @@ export class RegisterComponent implements OnInit { ...@@ -53,7 +67,9 @@ export class RegisterComponent implements OnInit {
postData(frm: any): void { postData(frm: any): void {
if (this.submitElement.classList.contains('disabled')) { return; } if (this.submitElement.classList.contains('disabled')) {
return;
}
this.submitElement.classList.add('disabled'); this.submitElement.classList.add('disabled');
if (this.form.get('name').invalid) { if (this.form.get('name').invalid) {
...@@ -148,10 +164,5 @@ export class RegisterComponent implements OnInit { ...@@ -148,10 +164,5 @@ export class RegisterComponent implements OnInit {
} }
get email(): AbstractControl { return this.form.get('email'); }
get password(): AbstractControl { return this.form.get('password'); }
get name(): AbstractControl { return this.form.get('name'); }
get username(): AbstractControl { return this.form.get('name'); }
} }
import { TestBed } from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import { RunCodeService } from './run-code.service'; import {RunCodeService} from './run-code.service';
describe('RunCodeService', () => { describe('RunCodeService', () => {
let service: RunCodeService; let service: RunCodeService;
......
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
import { Observable, of } from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
...@@ -9,6 +8,9 @@ export class RunCodeService { ...@@ -9,6 +8,9 @@ export class RunCodeService {
status = 'Compiling...'; status = 'Compiling...';
result = 0; result = 0;
constructor() {
}
run(): void { run(): void {
const output = `25 const output = `25
abcd abcd
...@@ -30,6 +32,4 @@ abcd ...@@ -30,6 +32,4 @@ abcd
this.result = 1; this.result = 1;
}, 6000); }, 6000);
} }
constructor() { }
} }
<div id="save-cover" [class.open]="isActive"></div> <div [class.open]="isActive" id="save-cover"></div>
<div id="save-popup" [class.open]="isActive"> <div [class.open]="isActive" id="save-popup">
<div *ngIf="!isUploading"> <div *ngIf="!isUploading">
<label for="filenameInput" id="filenameInputLabel">Enter Filename:</label><br> <label for="filenameInput" id="filenameInputLabel">Enter Filename:</label><br>
<input id="filenameInput" type="text" name="filenameInput" [(ngModel)]="file.filename"> <input [(ngModel)]="file.filename" id="filenameInput" name="filenameInput" type="text">
<span>{{file.language}}</span> <span>{{file.language}}</span>
<br> <br>
<button id="save-cancel" (click)="isActive = false">Cancel</button> <button (click)="isActive = false" id="save-cancel">Cancel</button>
<button id="save-done" [class.disabled]="file.filename === ''" (click)="file.filename !== '' && submitFile()">Done</button> <button (click)="file.filename !== '' && submitFile()" [class.disabled]="file.filename === ''" id="save-done">Done
</button>
</div> </div>
<div *ngIf="isUploading">Uploading...</div> <div *ngIf="isUploading">Uploading...</div>
</div> </div>
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { SaveFileComponent } from './save-file.component'; import {SaveFileComponent} from './save-file.component';
describe('SaveFileComponent', () => { describe('SaveFileComponent', () => {
let component: SaveFileComponent; let component: SaveFileComponent;
...@@ -8,9 +8,9 @@ describe('SaveFileComponent', () => { ...@@ -8,9 +8,9 @@ describe('SaveFileComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ SaveFileComponent ] declarations: [SaveFileComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import {Component, OnInit, Output, EventEmitter, Input} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {FileService} from '../file.service'; import {FileService} from '../file.service';
import {File} from '../file'; import {File} from '../file';
import {Location} from '@angular/common'; import {Location} from '@angular/common';
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { TestcaseStatusComponent } from './testcase-status.component'; import {TestcaseStatusComponent} from './testcase-status.component';
describe('TestcaseStatusComponent', () => { describe('TestcaseStatusComponent', () => {
let component: TestcaseStatusComponent; let component: TestcaseStatusComponent;
...@@ -8,9 +8,9 @@ describe('TestcaseStatusComponent', () => { ...@@ -8,9 +8,9 @@ describe('TestcaseStatusComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ TestcaseStatusComponent ] declarations: [TestcaseStatusComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
import { Component, OnInit } from '@angular/core'; import {Component, OnInit} from '@angular/core';
@Component({ @Component({
selector: 'app-testcase-status', selector: 'app-testcase-status',
...@@ -7,7 +7,8 @@ import { Component, OnInit } from '@angular/core'; ...@@ -7,7 +7,8 @@ import { Component, OnInit } from '@angular/core';
}) })
export class TestcaseStatusComponent implements OnInit { export class TestcaseStatusComponent implements OnInit {
constructor() { } constructor() {
}
ngOnInit(): void { ngOnInit(): void {
} }
......
<div class="container"> <div class="container">
<div class="card" id="user_cred"> <div class="card" id="user_cred">
<div id="grid1"> <div id="grid1">
<img id="profile-icon" src="{{user.img_url}}" alt="Profile Icon"> <img alt="Profile Icon" id="profile-icon" src="{{user.img_url}}">
<div class="name-and-id"> <div class="name-and-id">
<div class="tc"> <div class="tc">
<div>{{user.name}}</div> <div>{{user.name}}</div>
...@@ -9,8 +9,12 @@ ...@@ -9,8 +9,12 @@
<div class="inline-code">{{user.username}}</div> <div class="inline-code">{{user.username}}</div>
<div class="inline-code"><i class="lnr lnr-star"></i> {{user.rating}}</div> <div class="inline-code"><i class="lnr lnr-star"></i> {{user.rating}}</div>
<div> <div>
<a href="" id="edit"><button>Edit Details</button></a> <a href="" id="edit">
<a href="" id=" Logout" (click)="logout()"><button>Logout</button></a> <button>Edit Details</button>
</a>
<a (click)="logout()" href="" id=" Logout">
<button>Logout</button>
</a>
</div> </div>
</div> </div>
</div> </div>
...@@ -31,7 +35,7 @@ ...@@ -31,7 +35,7 @@
</tr> </tr>
</table> </table>
<div id="canvas"> <div id="canvas">
<canvas id="myChart" width="100px" height="100px"></canvas> <canvas height="100px" id="myChart" width="100px"></canvas>
</div> </div>
</div> </div>
</div> </div>
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
height: 106px; height: 106px;
vertical-align: middle; vertical-align: middle;
&>div { & > div {
margin: 4px; margin: 4px;
.lnr { .lnr {
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
color: #ffa; color: #ffa;
border-radius: 100%; border-radius: 100%;
box-shadow: 0 0 5px 5px #ff84 inset, box-shadow: 0 0 5px 5px #ff84 inset,
0 0 5px 5px #ff84; 0 0 5px 5px #ff84;
} }
} }
} }
......
import { ComponentFixture, TestBed } from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import { UserComponent } from './user.component'; import {UserComponent} from './user.component';
describe('UserComponent', () => { describe('UserComponent', () => {
let component: UserComponent; let component: UserComponent;
...@@ -8,9 +8,9 @@ describe('UserComponent', () => { ...@@ -8,9 +8,9 @@ describe('UserComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ UserComponent ] declarations: [UserComponent]
}) })
.compileComponents(); .compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
......
...@@ -7,32 +7,41 @@ var number, bumpOnly; ...@@ -7,32 +7,41 @@ var number, bumpOnly;
for (var i = 2; i < process.argv.length; i++) { for (var i = 2; i < process.argv.length; i++) {
if (process.argv[i] == "-bump") bumpOnly = true; if (process.argv[i] == "-bump") bumpOnly = true;
else if (/^\d+\.\d+\.\d+$/.test(process.argv[i])) number = process.argv[i]; else if (/^\d+\.\d+\.\d+$/.test(process.argv[i])) number = process.argv[i];
else { console.log("Bogus command line arg: " + process.argv[i]); process.exit(1); } else {
console.log("Bogus command line arg: " + process.argv[i]);
process.exit(1);
}
} }
if (!number) { console.log("Must give a version"); process.exit(1); } if (!number) {
console.log("Must give a version");
process.exit(1);
}
function rewrite(file, f) { function rewrite(file, f) {
fs.writeFileSync(file, f(fs.readFileSync(file, "utf8")), "utf8"); fs.writeFileSync(file, f(fs.readFileSync(file, "utf8")), "utf8");
} }
rewrite("src/edit/main.js", function(lib) { rewrite("src/edit/main.js", function (lib) {
return lib.replace(/CodeMirror\.version = "\d+\.\d+\.\d+"/, return lib.replace(/CodeMirror\.version = "\d+\.\d+\.\d+"/,
"CodeMirror.version = \"" + number + "\""); "CodeMirror.version = \"" + number + "\"");
}); });
function rewriteJSON(pack) { function rewriteJSON(pack) {
return pack.replace(/"version":\s*"\d+\.\d+\.\d+"/, "\"version\": \"" + number + "\""); return pack.replace(/"version":\s*"\d+\.\d+\.\d+"/, "\"version\": \"" + number + "\"");
} }
rewrite("package.json", rewriteJSON); rewrite("package.json", rewriteJSON);
rewrite("doc/manual.html", function(manual) { rewrite("doc/manual.html", function (manual) {
return manual.replace(/>version \d+\.\d+\.\d+<\/span>/, ">version " + number + "</span>"); return manual.replace(/>version \d+\.\d+\.\d+<\/span>/, ">version " + number + "</span>");
}); });
if (bumpOnly) process.exit(0); if (bumpOnly) process.exit(0);
child.exec("bash bin/authors.sh", function(){}); child.exec("bash bin/authors.sh", function () {
});
rewrite("index.html", function(index) { rewrite("index.html", function (index) {
return index.replace(/\.zip">\d+\.\d+\.\d+<\/a>/, return index.replace(/\.zip">\d+\.\d+\.\d+<\/a>/,
".zip\">" + number + "</a>"); ".zip\">" + number + "</a>");
}); });
...@@ -13,8 +13,8 @@ require("../mode/meta.js"); ...@@ -13,8 +13,8 @@ require("../mode/meta.js");
var sPos = process.argv.indexOf("-s"); var sPos = process.argv.indexOf("-s");
if (sPos == -1 || sPos == process.argv.length - 1) { if (sPos == -1 || sPos == process.argv.length - 1) {
console.error("Usage: source-highlight -s language"); console.error("Usage: source-highlight -s language");
process.exit(1); process.exit(1);
} }
var lang = process.argv[sPos + 1].toLowerCase(), modeName = lang; var lang = process.argv[sPos + 1].toLowerCase(), modeName = lang;
var found = CodeMirror.findModeByMIME(lang) || CodeMirror.findModeByName(lang) var found = CodeMirror.findModeByMIME(lang) || CodeMirror.findModeByName(lang)
...@@ -27,20 +27,24 @@ if (!CodeMirror.modes[modeName]) ...@@ -27,20 +27,24 @@ if (!CodeMirror.modes[modeName])
require("../mode/" + modeName + "/" + modeName + ".js"); require("../mode/" + modeName + "/" + modeName + ".js");
function esc(str) { function esc(str) {
return str.replace(/[<&]/g, function(ch) { return ch == "&" ? "&amp;" : "&lt;"; }); return str.replace(/[<&]/g, function (ch) {
return ch == "&" ? "&amp;" : "&lt;";
});
} }
var code = fs.readFileSync("/dev/stdin", "utf8"); var code = fs.readFileSync("/dev/stdin", "utf8");
var curStyle = null, accum = ""; var curStyle = null, accum = "";
function flush() { function flush() {
if (curStyle) process.stdout.write("<span class=\"" + curStyle.replace(/(^|\s+)/g, "$1cm-") + "\">" + esc(accum) + "</span>"); if (curStyle) process.stdout.write("<span class=\"" + curStyle.replace(/(^|\s+)/g, "$1cm-") + "\">" + esc(accum) + "</span>");
else process.stdout.write(esc(accum)); else process.stdout.write(esc(accum));
} }
CodeMirror.runMode(code, lang, function(text, style) { CodeMirror.runMode(code, lang, function (text, style) {
if (style != curStyle) { if (style != curStyle) {
flush(); flush();
curStyle = style; accum = text; curStyle = style;
accum = text;
} else { } else {
accum += text; accum += text;
} }
......
...@@ -2,15 +2,18 @@ ...@@ -2,15 +2,18 @@
<title>CodeMirror: Active Line Demo</title> <title>CodeMirror: Active Line Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<script src="../addon/selection/active-line.js"></script> <script src="../addon/selection/active-line.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
</style> border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,17 +28,16 @@ ...@@ -25,17 +28,16 @@
</div> </div>
<article> <article>
<h2>Active Line Demo</h2> <h2>Active Line Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:georss="http://www.georss.org/georss" xmlns:twitter="http://api.twitter.com">
xmlns:twitter="http://api.twitter.com">
<channel> <channel>
<title>Twitter / codemirror</title> <title>Twitter / codemirror</title>
<link>http://twitter.com/codemirror</link> <link>http://twitter.com/codemirror</link>
<atom:link type="application/rss+xml" <atom:link href="http://twitter.com/statuses/user_timeline/242283288.rss"
href="http://twitter.com/statuses/user_timeline/242283288.rss" rel="self"/> rel="self" type="application/rss+xml"/>
<description>Twitter updates from CodeMirror / codemirror.</description> <description>Twitter updates from CodeMirror / codemirror.</description>
<language>en-us</language> <language>en-us</language>
<ttl>40</ttl> <ttl>40</ttl>
...@@ -64,25 +66,25 @@ ...@@ -64,25 +66,25 @@
</channel> </channel>
</rss></textarea></form> </rss></textarea></form>
<script> <script>
var nonEmpty = false; var nonEmpty = false;
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "application/xml", mode: "application/xml",
styleActiveLine: true, styleActiveLine: true,
lineNumbers: true, lineNumbers: true,
lineWrapping: true lineWrapping: true
}); });
function toggleSelProp() { function toggleSelProp() {
nonEmpty = !nonEmpty; nonEmpty = !nonEmpty;
editor.setOption("styleActiveLine", {nonEmpty: nonEmpty}); editor.setOption("styleActiveLine", {nonEmpty: nonEmpty});
var label = nonEmpty ? 'Disable nonEmpty option' : 'Enable nonEmpty option'; var label = nonEmpty ? 'Disable nonEmpty option' : 'Enable nonEmpty option';
document.getElementById('toggleButton').innerText = label; document.getElementById('toggleButton').innerText = label;
} }
</script> </script>
<p>Styling the current cursor line.</p> <p>Styling the current cursor line.</p>
<button onclick="toggleSelProp()" id="toggleButton">Enable <code>nonEmpty</code> option</button> <button id="toggleButton" onclick="toggleSelProp()">Enable <code>nonEmpty</code> option</button>
</article> </article>
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<title>CodeMirror: Any Word Completion Demo</title> <title>CodeMirror: Any Word Completion Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/hint/show-hint.css"> <link href="../addon/hint/show-hint.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script> <script src="../addon/hint/show-hint.js"></script>
<script src="../addon/hint/anyword-hint.js"></script> <script src="../addon/hint/anyword-hint.js"></script>
...@@ -24,14 +24,14 @@ ...@@ -24,14 +24,14 @@
</div> </div>
<article> <article>
<h2>Any Word Completion Demo</h2> <h2>Any Word Completion Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
(function() { (function() {
"use strict"; "use strict";
var WORD = /[\w$]+/g, RANGE = 500; var WORD = /[\w$]+/g, RANGE = 500;
CodeMirror.registerHelper("hint", "anyword", function(editor, options) { CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
var word = options && options.word || WORD; var word = options && options.word || WORD;
var range = options && options.range || RANGE; var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line); var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
...@@ -42,12 +42,12 @@ ...@@ -42,12 +42,12 @@
var list = [], seen = {}; var list = [], seen = {};
function scan(dir) { function scan(dir) {
var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
for (; line != end; line += dir) { for (; line != end; line += dir) {
var text = editor.getLine(line), m; var text = editor.getLine(line), m;
word.lastIndex = 0; word.lastIndex = 0;
while (m = word.exec(text)) { while (m = word.exec(text)) {
if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) { if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) {
seen[m[0]] = true; seen[m[0]] = true;
list.push(m[0]); list.push(m[0]);
} }
...@@ -61,19 +61,19 @@ ...@@ -61,19 +61,19 @@
})(); })();
</textarea></form> </textarea></form>
<p>Press <strong>ctrl-space</strong> to activate autocompletion. The <p>Press <strong>ctrl-space</strong> to activate autocompletion. The
completion uses completion uses
the <a href="../doc/manual.html#addon_anyword-hint">anyword-hint.js</a> the <a href="../doc/manual.html#addon_anyword-hint">anyword-hint.js</a>
module, which simply looks at nearby words in the buffer and completes module, which simply looks at nearby words in the buffer and completes
to those.</p> to those.</p>
<script> <script>
CodeMirror.commands.autocomplete = function(cm) { CodeMirror.commands.autocomplete = function (cm) {
cm.showHint({hint: CodeMirror.hint.anyword}); cm.showHint({hint: CodeMirror.hint.anyword});
} }
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
extraKeys: {"Ctrl-Space": "autocomplete"} extraKeys: {"Ctrl-Space": "autocomplete"}
}); });
</script> </script>
</article> </article>
...@@ -2,14 +2,20 @@ ...@@ -2,14 +2,20 @@
<title>CodeMirror: Bi-directional Text Demo</title> <title>CodeMirror: Bi-directional Text Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
fieldset {border: none} border-top: 1px solid black;
border-bottom: 1px solid black;
}
fieldset {
border: none
}
</style> </style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,9 +31,9 @@ ...@@ -25,9 +31,9 @@
</div> </div>
<article> <article>
<h2>Bi-directional Text Demo</h2> <h2>Bi-directional Text Demo</h2>
<form><textarea id="code" name="code"><!-- Piece of the CodeMirror manual, 'translated' into Arabic by Google Translate --> <form><textarea id="code" name="code"><!-- Piece of the CodeMirror manual, 'translated' into Arabic by Google Translate -->
<!-- قطعة من دليل CodeMirror، "ترجم" إلى العربية بواسطة جوجل ترجمة --> <!-- قطعة من دليل CodeMirror، "ترجم" إلى العربية بواسطة جوجل ترجمة -->
<dl> <dl>
<dt id=option_value><code>value (string or Doc)</code></dt> <dt id=option_value><code>value (string or Doc)</code></dt>
...@@ -55,52 +61,57 @@ ...@@ -55,52 +61,57 @@
الطبقات إلى المحرر.</dd> الطبقات إلى المحرر.</dd>
</dl> </dl>
</textarea> </textarea>
<fieldset> <fieldset>
Editor default direction: Editor default direction:
<input type="radio" id="ltr" name="direction"/><label for="ltr">LTR</label> <input id="ltr" name="direction" type="radio"/><label for="ltr">LTR</label>
<input type="radio" id="rtl" name="direction"/><label for="rtl">RTL</label> <input id="rtl" name="direction" type="radio"/><label for="rtl">RTL</label>
</fieldset> </fieldset>
<fieldset> <fieldset>
HTML document direction: HTML document direction:
<input type="radio" id="htmlltr" name="htmldirection"/><label for="htmlltr">LTR</label> <input id="htmlltr" name="htmldirection" type="radio"/><label for="htmlltr">LTR</label>
<input type="radio" id="htmlrtl" name="htmldirection"/><label for="htmlrtl">RTL</label> <input id="htmlrtl" name="htmldirection" type="radio"/><label for="htmlrtl">RTL</label>
</fieldset> </fieldset>
<fieldset> <fieldset>
<input type="checkbox" id="rtlMoveVisually"/><label for="rtlMoveVisually">Use visual order for arrow key movement.</label> <input id="rtlMoveVisually" type="checkbox"/><label for="rtlMoveVisually">Use visual order for arrow key
</fieldset> movement.</label>
</form> </fieldset>
</form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/html", mode: "text/html",
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
direction: "rtl" direction: "rtl"
}); });
var dirRadios = {ltr: document.getElementById("ltr"), var dirRadios = {
rtl: document.getElementById("rtl")}; ltr: document.getElementById("ltr"),
dirRadios[editor.getOption("direction")].checked = true; rtl: document.getElementById("rtl")
dirRadios["rtl"].onchange = dirRadios["ltr"].onchange = function() { };
editor.setOption("direction", dirRadios["rtl"].checked ? "rtl" : "ltr"); dirRadios[editor.getOption("direction")].checked = true;
}; dirRadios["rtl"].onchange = dirRadios["ltr"].onchange = function () {
editor.setOption("direction", dirRadios["rtl"].checked ? "rtl" : "ltr");
};
var HtmlDirRadios = {ltr: document.getElementById("htmlltr"), var HtmlDirRadios = {
rtl: document.getElementById("htmlrtl")}; ltr: document.getElementById("htmlltr"),
HtmlDirRadios["ltr"].checked = true; rtl: document.getElementById("htmlrtl")
HtmlDirRadios["rtl"].onchange = HtmlDirRadios["ltr"].onchange = function() { };
document.dir = (HtmlDirRadios["rtl"].checked ? "rtl" : "ltr"); HtmlDirRadios["ltr"].checked = true;
}; HtmlDirRadios["rtl"].onchange = HtmlDirRadios["ltr"].onchange = function () {
document.dir = (HtmlDirRadios["rtl"].checked ? "rtl" : "ltr");
};
var moveCheckbox = document.getElementById("rtlMoveVisually"); var moveCheckbox = document.getElementById("rtlMoveVisually");
moveCheckbox.checked = editor.getOption("rtlMoveVisually"); moveCheckbox.checked = editor.getOption("rtlMoveVisually");
moveCheckbox.onchange = function() { moveCheckbox.onchange = function () {
editor.setOption("rtlMoveVisually", moveCheckbox.checked); editor.setOption("rtlMoveVisually", moveCheckbox.checked);
}; };
</script> </script>
<p>Demonstration of bi-directional text support. See <p>Demonstration of bi-directional text support. See
the <a href="http://marijnhaverbeke.nl/blog/cursor-in-bidi-text.html">related the <a href="http://marijnhaverbeke.nl/blog/cursor-in-bidi-text.html">related
blog post</a> for more background.</p> blog post</a> for more background.</p>
</article> </article>
...@@ -2,14 +2,22 @@ ...@@ -2,14 +2,22 @@
<title>CodeMirror: B-Tree visualization</title> <title>CodeMirror: B-Tree visualization</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<style> <style>
.lineblock { display: inline-block; margin: 1px; height: 5px; } .lineblock {
.CodeMirror {border: 1px solid #aaa; height: 400px} display: inline-block;
</style> margin: 1px;
height: 5px;
}
.CodeMirror {
border: 1px solid #aaa;
height: 400px
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -24,60 +32,69 @@ ...@@ -24,60 +32,69 @@
</div> </div>
<article> <article>
<h2>B-Tree visualization</h2> <h2>B-Tree visualization</h2>
<form><textarea id="code" name="code">type here, see a summary of the document b-tree below</textarea></form> <form><textarea id="code" name="code">type here, see a summary of the document b-tree below</textarea></form>
<div style="display: inline-block; height: 402px; overflow-y: auto" id="output"></div> <div id="output" style="display: inline-block; height: 402px; overflow-y: auto"></div>
<script id="me"> <script id="me">
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
lineWrapping: true lineWrapping: true
}); });
var updateTimeout; var updateTimeout;
editor.on("change", function(cm) { editor.on("change", function (cm) {
clearTimeout(updateTimeout); clearTimeout(updateTimeout);
updateTimeout = setTimeout(updateVisual, 200); updateTimeout = setTimeout(updateVisual, 200);
}); });
updateVisual(); updateVisual();
function updateVisual() { function updateVisual() {
var out = document.getElementById("output"); var out = document.getElementById("output");
out.innerHTML = ""; out.innerHTML = "";
function drawTree(out, node) { function drawTree(out, node) {
if (node.lines) { if (node.lines) {
out.appendChild(document.createElement("div")).innerHTML = out.appendChild(document.createElement("div")).innerHTML =
"<b>leaf</b>: " + node.lines.length + " lines, " + Math.round(node.height) + " px"; "<b>leaf</b>: " + node.lines.length + " lines, " + Math.round(node.height) + " px";
var lines = out.appendChild(document.createElement("div")); var lines = out.appendChild(document.createElement("div"));
lines.style.lineHeight = "6px"; lines.style.marginLeft = "10px"; lines.style.lineHeight = "6px";
for (var i = 0; i < node.lines.length; ++i) { lines.style.marginLeft = "10px";
var line = node.lines[i], lineElt = lines.appendChild(document.createElement("div")); for (var i = 0; i < node.lines.length; ++i) {
lineElt.className = "lineblock"; var line = node.lines[i], lineElt = lines.appendChild(document.createElement("div"));
var gray = Math.min(line.text.length * 3, 230), col = gray.toString(16); lineElt.className = "lineblock";
if (col.length == 1) col = "0" + col; var gray = Math.min(line.text.length * 3, 230), col = gray.toString(16);
lineElt.style.background = "#" + col + col + col; if (col.length == 1) col = "0" + col;
lineElt.style.width = Math.max(Math.round(line.height / 3), 1) + "px"; lineElt.style.background = "#" + col + col + col;
lineElt.style.width = Math.max(Math.round(line.height / 3), 1) + "px";
}
} else {
out.appendChild(document.createElement("div")).innerHTML =
"<b>node</b>: " + node.size + " lines, " + Math.round(node.height) + " px";
var sub = out.appendChild(document.createElement("div"));
sub.style.paddingLeft = "20px";
for (var i = 0; i < node.children.length; ++i)
drawTree(sub, node.children[i]);
}
} }
} else {
out.appendChild(document.createElement("div")).innerHTML = drawTree(out, editor.getDoc());
"<b>node</b>: " + node.size + " lines, " + Math.round(node.height) + " px";
var sub = out.appendChild(document.createElement("div"));
sub.style.paddingLeft = "20px";
for (var i = 0; i < node.children.length; ++i)
drawTree(sub, node.children[i]);
} }
}
drawTree(out, editor.getDoc());
}
function fillEditor() { function fillEditor() {
var sc = document.getElementById("me"); var sc = document.getElementById("me");
var doc = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "") + "\n"; var doc = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "") + "\n";
doc += doc; doc += doc; doc += doc; doc += doc; doc += doc; doc += doc; doc += doc;
editor.setValue(doc); doc += doc;
} doc += doc;
</script> doc += doc;
doc += doc;
doc += doc;
editor.setValue(doc);
}
</script>
<p><button onclick="fillEditor()">Add a lot of content</button></p> <p>
<button onclick="fillEditor()">Add a lot of content</button>
</p>
</article> </article>
...@@ -2,15 +2,18 @@ ...@@ -2,15 +2,18 @@
<title>CodeMirror: Multiple Buffer & Split View Demo</title> <title>CodeMirror: Multiple Buffer & Split View Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script> <script src="../mode/javascript/javascript.js"></script>
<script src="../mode/css/css.js"></script> <script src="../mode/css/css.js"></script>
<style id=style> <style id=style>
.CodeMirror {border: 1px solid black; height: 250px;} .CodeMirror {
</style> border: 1px solid black;
height: 250px;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,85 +28,90 @@ ...@@ -25,85 +28,90 @@
</div> </div>
<article> <article>
<h2>Multiple Buffer & Split View Demo</h2> <h2>Multiple Buffer & Split View Demo</h2>
<div id=code_top></div> <div id=code_top></div>
<div> <div>
Select buffer: <select id=buffers_top></select> Select buffer: <select id=buffers_top></select>
&nbsp; &nbsp; <button onclick="newBuf('top')">New buffer</button> &nbsp; &nbsp;
</div> <button onclick="newBuf('top')">New buffer</button>
<div id=code_bot></div> </div>
<div> <div id=code_bot></div>
Select buffer: <select id=buffers_bot></select> <div>
&nbsp; &nbsp; <button onclick="newBuf('bot')">New buffer</button> Select buffer: <select id=buffers_bot></select>
</div> &nbsp; &nbsp;
<button onclick="newBuf('bot')">New buffer</button>
<script id=script> </div>
var sel_top = document.getElementById("buffers_top");
CodeMirror.on(sel_top, "change", function() { <script id=script>
selectBuffer(ed_top, sel_top.options[sel_top.selectedIndex].value); var sel_top = document.getElementById("buffers_top");
}); CodeMirror.on(sel_top, "change", function () {
selectBuffer(ed_top, sel_top.options[sel_top.selectedIndex].value);
var sel_bot = document.getElementById("buffers_bot"); });
CodeMirror.on(sel_bot, "change", function() {
selectBuffer(ed_bot, sel_bot.options[sel_bot.selectedIndex].value); var sel_bot = document.getElementById("buffers_bot");
}); CodeMirror.on(sel_bot, "change", function () {
selectBuffer(ed_bot, sel_bot.options[sel_bot.selectedIndex].value);
var buffers = {}; });
function openBuffer(name, text, mode) { var buffers = {};
buffers[name] = CodeMirror.Doc(text, mode);
var opt = document.createElement("option"); function openBuffer(name, text, mode) {
opt.appendChild(document.createTextNode(name)); buffers[name] = CodeMirror.Doc(text, mode);
sel_top.appendChild(opt); var opt = document.createElement("option");
sel_bot.appendChild(opt.cloneNode(true)); opt.appendChild(document.createTextNode(name));
} sel_top.appendChild(opt);
sel_bot.appendChild(opt.cloneNode(true));
function newBuf(where) { }
var name = prompt("Name for the buffer", "*scratch*");
if (name == null) return; function newBuf(where) {
if (buffers.hasOwnProperty(name)) { var name = prompt("Name for the buffer", "*scratch*");
alert("There's already a buffer by that name."); if (name == null) return;
return; if (buffers.hasOwnProperty(name)) {
} alert("There's already a buffer by that name.");
openBuffer(name, "", "javascript"); return;
selectBuffer(where == "top" ? ed_top : ed_bot, name); }
var sel = where == "top" ? sel_top : sel_bot; openBuffer(name, "", "javascript");
sel.value = name; selectBuffer(where == "top" ? ed_top : ed_bot, name);
} var sel = where == "top" ? sel_top : sel_bot;
sel.value = name;
function selectBuffer(editor, name) { }
var buf = buffers[name];
if (buf.getEditor()) buf = buf.linkedDoc({sharedHist: true}); function selectBuffer(editor, name) {
var old = editor.swapDoc(buf); var buf = buffers[name];
var linked = old.iterLinkedDocs(function(doc) {linked = doc;}); if (buf.getEditor()) buf = buf.linkedDoc({sharedHist: true});
if (linked) { var old = editor.swapDoc(buf);
// Make sure the document in buffers is the one the other view is looking at var linked = old.iterLinkedDocs(function (doc) {
for (var name in buffers) if (buffers[name] == old) buffers[name] = linked; linked = doc;
old.unlinkDoc(linked); });
} if (linked) {
editor.focus(); // Make sure the document in buffers is the one the other view is looking at
} for (var name in buffers) if (buffers[name] == old) buffers[name] = linked;
old.unlinkDoc(linked);
function nodeContent(id) { }
var node = document.getElementById(id), val = node.textContent || node.innerText; editor.focus();
val = val.slice(val.match(/^\s*/)[0].length, val.length - val.match(/\s*$/)[0].length) + "\n"; }
return val;
} function nodeContent(id) {
openBuffer("js", nodeContent("script"), "javascript"); var node = document.getElementById(id), val = node.textContent || node.innerText;
openBuffer("css", nodeContent("style"), "css"); val = val.slice(val.match(/^\s*/)[0].length, val.length - val.match(/\s*$/)[0].length) + "\n";
return val;
var ed_top = CodeMirror(document.getElementById("code_top"), {lineNumbers: true}); }
selectBuffer(ed_top, "js");
var ed_bot = CodeMirror(document.getElementById("code_bot"), {lineNumbers: true}); openBuffer("js", nodeContent("script"), "javascript");
selectBuffer(ed_bot, "js"); openBuffer("css", nodeContent("style"), "css");
</script>
var ed_top = CodeMirror(document.getElementById("code_top"), {lineNumbers: true});
<p>Demonstration of selectBuffer(ed_top, "js");
var ed_bot = CodeMirror(document.getElementById("code_bot"), {lineNumbers: true});
selectBuffer(ed_bot, "js");
</script>
<p>Demonstration of
using <a href="../doc/manual.html#linkedDoc">linked documents</a> using <a href="../doc/manual.html#linkedDoc">linked documents</a>
to provide a split view on a document, and to provide a split view on a document, and
using <a href="../doc/manual.html#swapDoc"><code>swapDoc</code></a> using <a href="../doc/manual.html#swapDoc"><code>swapDoc</code></a>
to use a single editor to display multiple documents.</p> to use a single editor to display multiple documents.</p>
</article> </article>
...@@ -2,15 +2,17 @@ ...@@ -2,15 +2,17 @@
<title>CodeMirror: Mode-Changing Demo</title> <title>CodeMirror: Mode-Changing Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script> <script src="../mode/javascript/javascript.js"></script>
<script src="../mode/scheme/scheme.js"></script> <script src="../mode/scheme/scheme.js"></script>
<style> <style>
.CodeMirror {border: 1px solid black;} .CodeMirror {
</style> border: 1px solid black;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,8 +27,8 @@ ...@@ -25,8 +27,8 @@
</div> </div>
<article> <article>
<h2>Mode-Changing Demo</h2> <h2>Mode-Changing Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
;; If there is Scheme code in here, the editor will be in Scheme mode. ;; If there is Scheme code in here, the editor will be in Scheme mode.
;; If you put in JS instead, it'll switch to JS mode. ;; If you put in JS instead, it'll switch to JS mode.
...@@ -34,25 +36,27 @@ ...@@ -34,25 +36,27 @@
(* x x)) (* x x))
</textarea></form> </textarea></form>
<p>On changes to the content of the above editor, a (crude) script <p>On changes to the content of the above editor, a (crude) script
tries to auto-detect the language used, and switches the editor to tries to auto-detect the language used, and switches the editor to
either JavaScript or Scheme mode based on that.</p> either JavaScript or Scheme mode based on that.</p>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "scheme", mode: "scheme",
lineNumbers: true lineNumbers: true
}); });
var pending; var pending;
editor.on("change", function() { editor.on("change", function () {
clearTimeout(pending); clearTimeout(pending);
pending = setTimeout(update, 400); pending = setTimeout(update, 400);
}); });
function looksLikeScheme(code) {
return !/^\s*\(\s*function\b/.test(code) && /^\s*[;\(]/.test(code); function looksLikeScheme(code) {
} return !/^\s*\(\s*function\b/.test(code) && /^\s*[;\(]/.test(code);
function update() { }
editor.setOption("mode", looksLikeScheme(editor.getValue()) ? "scheme" : "javascript");
} function update() {
</script> editor.setOption("mode", looksLikeScheme(editor.getValue()) ? "scheme" : "javascript");
</article> }
</script>
</article>
...@@ -2,15 +2,18 @@ ...@@ -2,15 +2,18 @@
<title>CodeMirror: Closebrackets Demo</title> <title>CodeMirror: Closebrackets Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/edit/closebrackets.js"></script> <script src="../addon/edit/closebrackets.js"></script>
<script src="../mode/javascript/javascript.js"></script> <script src="../mode/javascript/javascript.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;} .CodeMirror {
</style> border-top: 1px solid #888;
border-bottom: 1px solid #888;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,28 +28,28 @@ ...@@ -25,28 +28,28 @@
</div> </div>
<article> <article>
<h2>Closebrackets Demo</h2> <h2>Closebrackets Demo</h2>
<form><textarea id="code" name="code">function Grid(width, height) { <form><textarea id="code" name="code">function Grid(width, height) {
this.width = width; this.width = width;
this.height = height; this.height = height;
this.cells = new Array(width * height); this.cells = new Array(width * height);
} }
Grid.prototype.valueAt = function(point) { Grid.prototype.valueAt = function(point) {
return this.cells[point.y * this.width + point.x]; return this.cells[point.y * this.width + point.x];
}; };
Grid.prototype.setValueAt = function(point, value) { Grid.prototype.setValueAt = function(point, value) {
this.cells[point.y * this.width + point.x] = value; this.cells[point.y * this.width + point.x] = value;
}; };
Grid.prototype.isInside = function(point) { Grid.prototype.isInside = function(point) {
return point.x >= 0 && point.y >= 0 && return point.x >= 0 && point.y >= 0 &&
point.x < this.width && point.y < this.height; point.x < this.width && point.y < this.height;
}; };
Grid.prototype.moveValue = function(from, to) { Grid.prototype.moveValue = function(from, to) {
this.setValueAt(to, this.valueAt(from)); this.setValueAt(to, this.valueAt(from));
this.setValueAt(from, undefined); this.setValueAt(from, undefined);
};</textarea></form> };</textarea></form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {autoCloseBrackets: true}); var editor = CodeMirror.fromTextArea(document.getElementById("code"), {autoCloseBrackets: true});
</script> </script>
</article> </article>
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
<title>CodeMirror: Close-Tag Demo</title> <title>CodeMirror: Close-Tag Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/edit/closetag.js"></script> <script src="../addon/edit/closetag.js"></script>
<script src="../addon/fold/xml-fold.js"></script> <script src="../addon/fold/xml-fold.js"></script>
...@@ -13,8 +13,11 @@ ...@@ -13,8 +13,11 @@
<script src="../mode/css/css.js"></script> <script src="../mode/css/css.js"></script>
<script src="../mode/htmlmixed/htmlmixed.js"></script> <script src="../mode/htmlmixed/htmlmixed.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;} .CodeMirror {
</style> border-top: 1px solid #888;
border-bottom: 1px solid #888;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -29,13 +32,13 @@ ...@@ -29,13 +32,13 @@
</div> </div>
<article> <article>
<h2>Close-Tag Demo</h2> <h2>Close-Tag Demo</h2>
<form><textarea id="code" name="code"><html</textarea></form> <form><textarea id="code" name="code"><html</textarea></form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: 'text/html', mode: 'text/html',
autoCloseTags: true autoCloseTags: true
}); });
</script> </script>
</article> </article>
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<title>CodeMirror: Autocomplete Demo</title> <title>CodeMirror: Autocomplete Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/hint/show-hint.css"> <link href="../addon/hint/show-hint.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script> <script src="../addon/hint/show-hint.js"></script>
<script src="../addon/hint/javascript-hint.js"></script> <script src="../addon/hint/javascript-hint.js"></script>
...@@ -26,11 +26,11 @@ ...@@ -26,11 +26,11 @@
</div> </div>
<article> <article>
<h2>Autocomplete Demo</h2> <h2>Autocomplete Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
function getCompletions(token, context) { function getCompletions(token, context) {
var found = [], start = token.string; var found = [], start = token.string;
function maybeAdd(str) { function maybeAdd(str) {
if (str.indexOf(start) == 0) found.push(str); if (str.indexOf(start) == 0) found.push(str);
} }
function gatherCompletions(obj) { function gatherCompletions(obj) {
...@@ -65,62 +65,64 @@ function getCompletions(token, context) { ...@@ -65,62 +65,64 @@ function getCompletions(token, context) {
} }
</textarea></form> </textarea></form>
<p>Press <strong>ctrl-space</strong> to activate autocompletion. Built <p>Press <strong>ctrl-space</strong> to activate autocompletion. Built
on top of the <a href="../doc/manual.html#addon_show-hint"><code>show-hint</code></a> on top of the <a href="../doc/manual.html#addon_show-hint"><code>show-hint</code></a>
and <a href="../doc/manual.html#addon_javascript-hint"><code>javascript-hint</code></a> and <a href="../doc/manual.html#addon_javascript-hint"><code>javascript-hint</code></a>
addons.</p> addons.</p>
<form><textarea style="display: none" id="synonyms" name="synonyms"> <form><textarea id="synonyms" name="synonyms" style="display: none">
Here, the completion use an asynchronous hinting functions to provide Here, the completion use an asynchronous hinting functions to provide
synonyms for each words. If your browser support `Promises`, the synonyms for each words. If your browser support `Promises`, the
hinting function can also return one. hinting function can also return one.
</textarea></form> </textarea></form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
extraKeys: {"Ctrl-Space": "autocomplete"}, extraKeys: {"Ctrl-Space": "autocomplete"},
mode: {name: "javascript", globalVars: true} mode: {name: "javascript", globalVars: true}
}); });
if (typeof Promise !== "undefined") { if (typeof Promise !== "undefined") {
var comp = [ var comp = [
["here", "hither"], ["here", "hither"],
["asynchronous", "nonsynchronous"], ["asynchronous", "nonsynchronous"],
["completion", "achievement", "conclusion", "culmination", "expirations"], ["completion", "achievement", "conclusion", "culmination", "expirations"],
["hinting", "advive", "broach", "imply"], ["hinting", "advive", "broach", "imply"],
["function","action"], ["function", "action"],
["provide", "add", "bring", "give"], ["provide", "add", "bring", "give"],
["synonyms", "equivalents"], ["synonyms", "equivalents"],
["words", "token"], ["words", "token"],
["each", "every"], ["each", "every"],
] ]
function synonyms(cm, option) { function synonyms(cm, option) {
return new Promise(function(accept) { return new Promise(function (accept) {
setTimeout(function() { setTimeout(function () {
var cursor = cm.getCursor(), line = cm.getLine(cursor.line) var cursor = cm.getCursor(), line = cm.getLine(cursor.line)
var start = cursor.ch, end = cursor.ch var start = cursor.ch, end = cursor.ch
while (start && /\w/.test(line.charAt(start - 1))) --start while (start && /\w/.test(line.charAt(start - 1))) --start
while (end < line.length && /\w/.test(line.charAt(end))) ++end while (end < line.length && /\w/.test(line.charAt(end))) ++end
var word = line.slice(start, end).toLowerCase() var word = line.slice(start, end).toLowerCase()
for (var i = 0; i < comp.length; i++) if (comp[i].indexOf(word) != -1) for (var i = 0; i < comp.length; i++) if (comp[i].indexOf(word) != -1)
return accept({list: comp[i], return accept({
from: CodeMirror.Pos(cursor.line, start), list: comp[i],
to: CodeMirror.Pos(cursor.line, end)}) from: CodeMirror.Pos(cursor.line, start),
return accept(null) to: CodeMirror.Pos(cursor.line, end)
}, 100) })
}) return accept(null)
} }, 100)
})
}
var editor2 = CodeMirror.fromTextArea(document.getElementById("synonyms"), { var editor2 = CodeMirror.fromTextArea(document.getElementById("synonyms"), {
extraKeys: {"Ctrl-Space": "autocomplete"}, extraKeys: {"Ctrl-Space": "autocomplete"},
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
mode: "text/x-markdown", mode: "text/x-markdown",
hintOptions: {hint: synonyms} hintOptions: {hint: synonyms}
}) })
} }
</script> </script>
</article> </article>
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<title>CodeMirror: Emacs bindings demo</title> <title>CodeMirror: Emacs bindings demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/dialog/dialog.css"> <link href="../addon/dialog/dialog.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/clike/clike.js"></script> <script src="../mode/clike/clike.js"></script>
<script src="../keymap/emacs.js"></script> <script src="../keymap/emacs.js"></script>
...@@ -15,8 +15,11 @@ ...@@ -15,8 +15,11 @@
<script src="../addon/search/searchcursor.js"></script> <script src="../addon/search/searchcursor.js"></script>
<script src="../addon/search/search.js"></script> <script src="../addon/search/search.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;} .CodeMirror {
</style> border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -31,16 +34,16 @@ ...@@ -31,16 +34,16 @@
</div> </div>
<article> <article>
<h2>Emacs bindings demo</h2> <h2>Emacs bindings demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
#include "syscalls.h" #include "syscalls.h"
/* getchar: simple buffered version */ /* getchar: simple buffered version */
int getchar(void) int getchar(void)
{ {
static char buf[BUFSIZ]; static char buf[BUFSIZ];
static char *bufp = buf; static char *bufp = buf;
static int n = 0; static int n = 0;
if (n == 0) { /* buffer is empty */ if (n == 0) { /* buffer is empty */
n = read(0, buf, sizeof buf); n = read(0, buf, sizeof buf);
bufp = buf; bufp = buf;
} }
...@@ -48,29 +51,31 @@ int getchar(void) ...@@ -48,29 +51,31 @@ int getchar(void)
} }
</textarea></form> </textarea></form>
<p>The emacs keybindings are enabled by <p>The emacs keybindings are enabled by
including <a href="../keymap/emacs.js">keymap/emacs.js</a> and setting including <a href="../keymap/emacs.js">keymap/emacs.js</a> and setting
the <code>keyMap</code> option to <code>"emacs"</code>. Because the <code>keyMap</code> option to <code>"emacs"</code>. Because
CodeMirror's internal API is quite different from Emacs, they are only CodeMirror's internal API is quite different from Emacs, they are only
a loose approximation of actual emacs bindings, though.</p> a loose approximation of actual emacs bindings, though.</p>
<p>Also note that a lot of browsers disallow certain keys from being <p>Also note that a lot of browsers disallow certain keys from being
captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the
result that idiomatic use of Emacs keys will constantly close your tab result that idiomatic use of Emacs keys will constantly close your tab
or open a new window.</p> or open a new window.</p>
<script> <script>
CodeMirror.commands.save = function() { CodeMirror.commands.save = function () {
var elt = editor.getWrapperElement(); var elt = editor.getWrapperElement();
elt.style.background = "#def"; elt.style.background = "#def";
setTimeout(function() { elt.style.background = ""; }, 300); setTimeout(function () {
}; elt.style.background = "";
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { }, 300);
lineNumbers: true, };
mode: "text/x-csrc", var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
matchBrackets: true, lineNumbers: true,
keyMap: "emacs" mode: "text/x-csrc",
}); matchBrackets: true,
</script> keyMap: "emacs"
});
</script>
</article> </article>
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<title>CodeMirror: Code Folding Demo</title> <title>CodeMirror: Code Folding Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<style> <style>
.some-css { .some-css {
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
} }
</style> </style>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/fold/foldgutter.css" /> <link href="../addon/fold/foldgutter.css" rel="stylesheet"/>
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/fold/foldcode.js"></script> <script src="../addon/fold/foldcode.js"></script>
<script src="../addon/fold/foldgutter.js"></script> <script src="../addon/fold/foldgutter.js"></script>
...@@ -29,7 +29,10 @@ ...@@ -29,7 +29,10 @@
<script src="../mode/python/python.js"></script> <script src="../mode/python/python.js"></script>
<script src="../mode/markdown/markdown.js"></script> <script src="../mode/markdown/markdown.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style> </style>
</head> </head>
...@@ -51,11 +54,11 @@ ...@@ -51,11 +54,11 @@
<h2>Code Folding Demo</h2> <h2>Code Folding Demo</h2>
<form> <form>
<div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br> <div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br>
<textarea id="code" name="code"></textarea></div> <textarea id="code" name="code"></textarea></div>
<div style="max-width: 50em; margin-bottom: 1em">HTML:<br> <div style="max-width: 50em; margin-bottom: 1em">HTML:<br>
<textarea id="code-html" name="code-html"></textarea></div> <textarea id="code-html" name="code-html"></textarea></div>
<div style="max-width: 50em; margin-bottom: 1em">JSON with custom widget:<br> <div style="max-width: 50em; margin-bottom: 1em">JSON with custom widget:<br>
<textarea id="code-json" name="code-json"> <textarea id="code-json" name="code-json">
{ {
"menu": { "menu": {
"id": "file", "id": "file",
...@@ -63,15 +66,15 @@ ...@@ -63,15 +66,15 @@
"popup": { "popup": {
"menuitem": [ "menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"}, {"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"}, {"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"} {"value": "Close", "onclick": "CloseDoc()"}
] ]
}
} }
}
} }
</textarea></div> </textarea></div>
<div style="max-width: 50em">Python:<br> <div style="max-width: 50em">Python:<br>
<textarea id="code-python" name="code"> <textarea id="code-python" name="code">
def foo(): def foo():
do_some_stuff() do_some_stuff()
here here
...@@ -89,96 +92,118 @@ class Bar: ...@@ -89,96 +92,118 @@ class Bar:
# A comment</textarea></div> # A comment</textarea></div>
<div style="max-width: 50em">Markdown:<br> <div style="max-width: 50em">Markdown:<br>
<textarea id="code-markdown" name="code"></textarea></div> <textarea id="code-markdown" name="code"></textarea></div>
</form> </form>
<script id="script"> <script id="script">
/* /*
* Demonstration of code folding * Demonstration of code folding
*/ */
window.onload = function() { window.onload = function () {
var te = document.getElementById("code"); var te = document.getElementById("code");
var sc = document.getElementById("script"); var sc = document.getElementById("script");
te.value = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, ""); te.value = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "");
sc.innerHTML = ""; sc.innerHTML = "";
var te_html = document.getElementById("code-html"); var te_html = document.getElementById("code-html");
te_html.value = document.documentElement.innerHTML; te_html.value = document.documentElement.innerHTML;
var te_python = document.getElementById("code-python"); var te_python = document.getElementById("code-python");
var te_markdown = document.getElementById("code-markdown"); var te_markdown = document.getElementById("code-markdown");
te_markdown.value = "# Foo\n## Bar\n\nblah blah\n\n## Baz\n\nblah blah\n\n# Quux\n\nblah blah\n" te_markdown.value = "# Foo\n## Bar\n\nblah blah\n\n## Baz\n\nblah blah\n\n# Quux\n\nblah blah\n"
var te_json = document.getElementById("code-json"); var te_json = document.getElementById("code-json");
window.editor = CodeMirror.fromTextArea(te, { window.editor = CodeMirror.fromTextArea(te, {
mode: "javascript", mode: "javascript",
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, extraKeys: {
foldGutter: true, "Ctrl-Q": function (cm) {
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] cm.foldCode(cm.getCursor());
}); }
editor.foldCode(CodeMirror.Pos(13, 0)); },
foldGutter: true,
window.editor_json = CodeMirror.fromTextArea(te_json, { gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
mode: {name: "javascript", json: true}, });
lineNumbers: true, editor.foldCode(CodeMirror.Pos(13, 0));
lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, window.editor_json = CodeMirror.fromTextArea(te_json, {
foldGutter: true, mode: {name: "javascript", json: true},
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], lineNumbers: true,
foldOptions: { lineWrapping: true,
widget: (from, to) => { extraKeys: {
var count = undefined; "Ctrl-Q": function (cm) {
cm.foldCode(cm.getCursor());
// Get open / close token }
var startToken = '{', endToken = '}'; },
var prevLine = window.editor_json.getLine(from.line); foldGutter: true,
if (prevLine.lastIndexOf('[') > prevLine.lastIndexOf('{')) { gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
startToken = '[', endToken = ']'; foldOptions: {
widget: (from, to) => {
var count = undefined;
// Get open / close token
var startToken = '{', endToken = '}';
var prevLine = window.editor_json.getLine(from.line);
if (prevLine.lastIndexOf('[') > prevLine.lastIndexOf('{')) {
startToken = '[', endToken = ']';
}
// Get json content
var internal = window.editor_json.getRange(from, to);
var toParse = startToken + internal + endToken;
// Get key count
try {
var parsed = JSON.parse(toParse);
count = Object.keys(parsed).length;
} catch (e) {
}
return count ? `\u21A4${count}\u21A6` : '\u2194';
}
} }
});
// Get json content editor_json.foldCode(CodeMirror.Pos(5, 0));
var internal = window.editor_json.getRange(from, to);
var toParse = startToken + internal + endToken; window.editor_html = CodeMirror.fromTextArea(te_html, {
mode: "text/html",
// Get key count lineNumbers: true,
try { lineWrapping: true,
var parsed = JSON.parse(toParse); extraKeys: {
count = Object.keys(parsed).length; "Ctrl-Q": function (cm) {
} catch(e) { } cm.foldCode(cm.getCursor());
}
return count ? `\u21A4${count}\u21A6` : '\u2194'; },
} foldGutter: true,
} gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
}); });
editor_json.foldCode(CodeMirror.Pos(5, 0)); editor_html.foldCode(CodeMirror.Pos(0, 0));
editor_html.foldCode(CodeMirror.Pos(34, 0));
window.editor_html = CodeMirror.fromTextArea(te_html, {
mode: "text/html", window.editor_python = CodeMirror.fromTextArea(te_python, {
lineNumbers: true, mode: "python",
lineWrapping: true, lineNumbers: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, extraKeys: {
foldGutter: true, "Ctrl-Q": function (cm) {
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] cm.foldCode(cm.getCursor());
}); }
editor_html.foldCode(CodeMirror.Pos(0, 0)); },
editor_html.foldCode(CodeMirror.Pos(34, 0)); foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
window.editor_python = CodeMirror.fromTextArea(te_python, { });
mode: "python",
lineNumbers: true, window.editor_markdown = CodeMirror.fromTextArea(te_markdown, {
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, mode: "markdown",
foldGutter: true, lineNumbers: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] lineWrapping: true,
}); extraKeys: {
"Ctrl-Q": function (cm) {
window.editor_markdown = CodeMirror.fromTextArea(te_markdown, { cm.foldCode(cm.getCursor());
mode: "markdown", }
lineNumbers: true, },
lineWrapping: true, foldGutter: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
foldGutter: true, });
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] };
}); <
}; /script>
</script> < /article>
</article> < /body>
</body>
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
<title>CodeMirror: Full Screen Editing</title> <title>CodeMirror: Full Screen Editing</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/display/fullscreen.css"> <link href="../addon/display/fullscreen.css" rel="stylesheet">
<link rel="stylesheet" href="../theme/night.css"> <link href="../theme/night.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<script src="../addon/display/fullscreen.js"></script> <script src="../addon/display/fullscreen.js"></script>
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
</div> </div>
<article> <article>
<h2>Full Screen Editing</h2> <h2>Full Screen Editing</h2>
<form><textarea id="code" name="code" rows="5"> <form><textarea id="code" name="code" rows="5">
<dl> <dl>
<dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt> <dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt>
<dd>Whether, when indenting, the first N*<code>tabSize</code> <dd>Whether, when indenting, the first N*<code>tabSize</code>
...@@ -65,19 +65,19 @@ ...@@ -65,19 +65,19 @@
lineNumbers: true, lineNumbers: true,
theme: "night", theme: "night",
extraKeys: { extraKeys: {
"F11": function(cm) { "F11": function (cm) {
cm.setOption("fullScreen", !cm.getOption("fullScreen")); cm.setOption("fullScreen", !cm.getOption("fullScreen"));
}, },
"Esc": function(cm) { "Esc": function (cm) {
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false); if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
} }
} }
}); });
</script> </script>
<p>Demonstration of <p>Demonstration of
the <a href="../doc/manual.html#addon_fullscreen">fullscreen</a> the <a href="../doc/manual.html#addon_fullscreen">fullscreen</a>
addon. Press <strong>F11</strong> when cursor is in the editor to addon. Press <strong>F11</strong> when cursor is in the editor to
toggle full screen editing. <strong>Esc</strong> can also be used toggle full screen editing. <strong>Esc</strong> can also be used
to <i>exit</i> full screen editing.</p> to <i>exit</i> full screen editing.</p>
</article> </article>
...@@ -2,14 +2,17 @@ ...@@ -2,14 +2,17 @@
<title>CodeMirror: Hard-wrapping Demo</title> <title>CodeMirror: Hard-wrapping Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/markdown/markdown.js"></script> <script src="../mode/markdown/markdown.js"></script>
<script src="../addon/wrap/hardwrap.js"></script> <script src="../addon/wrap/hardwrap.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style> </style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,8 +28,8 @@ ...@@ -25,8 +28,8 @@
</div> </div>
<article> <article>
<h2>Hard-wrapping Demo</h2> <h2>Hard-wrapping Demo</h2>
<form><textarea id="code" name="code">Lorem ipsum dolor sit amet, vim augue dictas constituto ex, <form><textarea id="code" name="code">Lorem ipsum dolor sit amet, vim augue dictas constituto ex,
sit falli simul viderer te. Graeco scaevola maluisset sit sit falli simul viderer te. Graeco scaevola maluisset sit
ut, in idque viris praesent sea. Ea sea eirmod indoctum ut, in idque viris praesent sea. Ea sea eirmod indoctum
repudiare. Vel noluisse suscipit pericula ut. In ius nulla repudiare. Vel noluisse suscipit pericula ut. In ius nulla
...@@ -46,30 +49,32 @@ id, quas doming malorum nec ad. Tollit eruditi vivendum ad ...@@ -46,30 +49,32 @@ id, quas doming malorum nec ad. Tollit eruditi vivendum ad
ius, eos soleat ignota ad. ius, eos soleat ignota ad.
</textarea></form> </textarea></form>
<p>Demonstration of <p>Demonstration of
the <a href="../doc/manual.html#addon_hardwrap">hardwrap</a> addon. the <a href="../doc/manual.html#addon_hardwrap">hardwrap</a> addon.
The above editor has its change event hooked up to The above editor has its change event hooked up to
the <code>wrapParagraphsInRange</code> method, so that the paragraphs the <code>wrapParagraphsInRange</code> method, so that the paragraphs
are reflown as you are typing.</p> are reflown as you are typing.</p>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "markdown", mode: "markdown",
lineNumbers: true, lineNumbers: true,
extraKeys: { extraKeys: {
"Ctrl-Q": function(cm) { cm.wrapParagraph(cm.getCursor(), options); } "Ctrl-Q": function (cm) {
} cm.wrapParagraph(cm.getCursor(), options);
}); }
var wait, options = {column: 60}, changing = false; }
editor.on("change", function(cm, change) { });
if (changing) return; var wait, options = {column: 60}, changing = false;
clearTimeout(wait); editor.on("change", function (cm, change) {
wait = setTimeout(function() { if (changing) return;
changing = true; clearTimeout(wait);
cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options); wait = setTimeout(function () {
changing = false; changing = true;
}, 200); cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options);
}); changing = false;
</script> }, 200);
});
</script>
</article> </article>
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
<head> <head>
<title>CodeMirror: HTML completion demo</title> <title>CodeMirror: HTML completion demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/hint/show-hint.css"> <link href="../addon/hint/show-hint.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script> <script src="../addon/hint/show-hint.js"></script>
<script src="../addon/hint/xml-hint.js"></script> <script src="../addon/hint/xml-hint.js"></script>
...@@ -16,41 +16,44 @@ ...@@ -16,41 +16,44 @@
<script src="../mode/css/css.js"></script> <script src="../mode/css/css.js"></script>
<script src="../mode/htmlmixed/htmlmixed.js"></script> <script src="../mode/htmlmixed/htmlmixed.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;} .CodeMirror {
border-top: 1px solid #888;
border-bottom: 1px solid #888;
}
</style> </style>
</head> </head>
<body> <body>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
<ul> <ul>
<li><a href="../index.html">Home</a> <li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a> <li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a> <li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul> </ul>
<ul> <ul>
<li><a class=active href="#">HTML completion</a> <li><a class=active href="#">HTML completion</a>
</ul> </ul>
</div> </div>
<article> <article>
<h2>HTML completion demo</h2> <h2>HTML completion demo</h2>
<p>Shows the <a href="xmlcomplete.html">XML completer</a> <p>Shows the <a href="xmlcomplete.html">XML completer</a>
parameterized with information about the tags in HTML. parameterized with information about the tags in HTML.
Press <strong>ctrl-space</strong> to activate completion.</p> Press <strong>ctrl-space</strong> to activate completion.</p>
<div id="code"></div> <div id="code"></div>
<script> <script>
window.onload = function() { window.onload = function () {
editor = CodeMirror(document.getElementById("code"), { editor = CodeMirror(document.getElementById("code"), {
mode: "text/html", mode: "text/html",
extraKeys: {"Ctrl-Space": "autocomplete"}, extraKeys: {"Ctrl-Space": "autocomplete"},
value: document.documentElement.innerHTML value: document.documentElement.innerHTML
}); });
}; };
</script> </script>
</article> </article>
</body> </body>
...@@ -2,15 +2,21 @@ ...@@ -2,15 +2,21 @@
<title>CodeMirror: Indented wrapped line demo</title> <title>CodeMirror: Indented wrapped line demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
.CodeMirror pre > * { text-indent: 0px; } border-top: 1px solid black;
</style> border-bottom: 1px solid black;
}
.CodeMirror pre > * {
text-indent: 0px;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,35 +31,38 @@ ...@@ -25,35 +31,38 @@
</div> </div>
<article> <article>
<h2>Indented wrapped line demo</h2> <h2>Indented wrapped line demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
<!doctype html> <!doctype html>
<body> <body>
<h2 id="overview">Overview</h2> <h2 id="overview">Overview</h2>
<p>CodeMirror is a code-editor component that can be embedded in Web pages. The core library provides <em>only</em> the editor component, no accompanying buttons, auto-completion, or other IDE functionality. It does provide a rich API on top of which such functionality can be straightforwardly implemented. See the <a href="#addons">add-ons</a> included in the distribution, and the <a href="https://github.com/jagthedrummer/codemirror-ui">CodeMirror UI</a> project, for reusable implementations of extra features.</p> <p>CodeMirror is a code-editor component that can be embedded in Web pages. The core library provides <em>only</em> the editor component, no accompanying buttons, auto-completion, or other IDE functionality. It does provide a rich API on top of which such functionality can be straightforwardly implemented. See the <a
href="#addons">add-ons</a> included in the distribution, and the <a
href="https://github.com/jagthedrummer/codemirror-ui">CodeMirror UI</a> project, for reusable implementations of extra features.</p>
<p>CodeMirror works with language-specific modes. Modes are JavaScript programs that help color (and optionally indent) text written in a given language. The distribution comes with a number of modes (see the <a href="../mode/"><code>mode/</code></a> directory), and it isn't hard to <a href="#modeapi">write new ones</a> for other languages.</p> <p>CodeMirror works with language-specific modes. Modes are JavaScript programs that help color (and optionally indent) text written in a given language. The distribution comes with a number of modes (see the <a
href="../mode/"><code>mode/</code></a> directory), and it isn't hard to <a href="#modeapi">write new ones</a> for other languages.</p>
</body> </body>
</textarea></form> </textarea></form>
<p>This page uses a hack on top of the <code>"renderLine"</code> <p>This page uses a hack on top of the <code>"renderLine"</code>
event to make wrapped text line up with the base indentation of event to make wrapped text line up with the base indentation of
the line.</p> the line.</p>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
mode: "text/html" mode: "text/html"
}); });
var charWidth = editor.defaultCharWidth(), basePadding = 4; var charWidth = editor.defaultCharWidth(), basePadding = 4;
editor.on("renderLine", function(cm, line, elt) { editor.on("renderLine", function (cm, line, elt) {
var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth; var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth;
elt.style.textIndent = "-" + off + "px"; elt.style.textIndent = "-" + off + "px";
elt.style.paddingLeft = (basePadding + off) + "px"; elt.style.paddingLeft = (basePadding + off) + "px";
}); });
editor.refresh(); editor.refresh();
</script> </script>
</article> </article>
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<title>CodeMirror: Linter Demo</title> <title>CodeMirror: Linter Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/lint/lint.css"> <link href="../addon/lint/lint.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script> <script src="../mode/javascript/javascript.js"></script>
<script src="../mode/css/css.js"></script> <script src="../mode/css/css.js"></script>
...@@ -17,8 +17,10 @@ ...@@ -17,8 +17,10 @@
<script src="../addon/lint/json-lint.js"></script> <script src="../addon/lint/json-lint.js"></script>
<script src="../addon/lint/css-lint.js"></script> <script src="../addon/lint/css-lint.js"></script>
<style> <style>
.CodeMirror {border: 1px solid black;} .CodeMirror {
</style> border: 1px solid black;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -33,29 +35,29 @@ ...@@ -33,29 +35,29 @@
</div> </div>
<article> <article>
<h2>Linter Demo</h2> <h2>Linter Demo</h2>
<p><textarea id="code-js">var widgets = [] <p><textarea id="code-js">var widgets = []
function updateHints() { function updateHints() {
editor.operation(function(){ editor.operation(function(){
for (var i = 0; i < widgets.length.; ++i) for (var i = 0; i < widgets.length.; ++i)
editor.removeLineWidget(widgets[i]); editor.removeLineWidget(widgets[i]);
widgets.length = 0; widgets.length = 0;
JSHINT(editor.getValue()); JSHINT(editor.getValue());
for (var i = 0; i < JSHINT.errors.length; ++i) { for(var i = 0; i < JSHINT.errors.length; ++i) {
var err = JSHINT.errors[i]; var err = JSHINT.errors[i];
if (!err) continue; if (!err) continue;
var msg = document.createElement("div"); var msg = document.createElement("div");
var icon = msg.appendChild(document.createElement("span")); var icon = msg.appendChild(document.createElement("span"));
icon.innerHTML = "!!"; icon.innerHTML = "!!";
icon.className = "lint-error-icon"; icon.className = "lint-error-icon";
msg.appendChild(document.createTextNode(err.reason)); msg.appendChild(document.createTextNode(err.reason));
msg.className = "lint-error"; msg.className = "lint-error";
widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true})); widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true}));
} }
}); });
var info = editor.getScrollInfo(); var info = editor.getScrollInfo();
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top; var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
if (info.top + info.clientHeight < after) if (info.top + info.clientHeight < after)
...@@ -63,29 +65,29 @@ function updateHints() { ...@@ -63,29 +65,29 @@ function updateHints() {
} }
</textarea></p> </textarea></p>
<p><textarea id="code-json">[ <p><textarea id="code-json">[
{ {
_id: "post 1", _id: "post 1",
"author": "Bob", "author": "Bob",
"content": "...", "content": "...",
"page_views": 5 "page_views": 5
}, },
{ {
"_id": "post 2", "_id": "post 2",
"author": "Bob", "author": "Bob",
"content": "...", "content": "...",
"page_views": 9 "page_views": 9
}, },
{ {
"_id": "post 3", "_id": "post 3",
"author": "Bob", "author": "Bob",
"content": "...", "content": "...",
"page_views": 8 "page_views": 8
} }
] ]
</textarea></p> </textarea></p>
<p><textarea id="code-css">@charset "UTF-8"; <p><textarea id="code-css">@charset "UTF-8";
@import url("booya.css") print, screen; @import url("booya.css") print, screen;
@import "whatup.css" screen; @import "whatup.css" screen;
...@@ -100,7 +102,7 @@ function updateHints() { ...@@ -100,7 +102,7 @@ function updateHints() {
/*Warning: empty ruleset */ /*Warning: empty ruleset */
.foo { .foo {
} }
h1 { h1 {
font-weight: bold; font-weight: bold;
...@@ -121,10 +123,10 @@ li.inline { ...@@ -121,10 +123,10 @@ li.inline {
} }
li.last { li.last {
display: inline; display: inline;
padding-left: 3px !important; padding-left: 3px !important;
padding-right: 3px; padding-right: 3px;
border-right: 0px; border-right: 0px;
} }
@media print { @media print {
...@@ -134,10 +136,10 @@ li.last { ...@@ -134,10 +136,10 @@ li.last {
} }
@page { @page {
margin: 10%; margin: 10%;
counter-increment: page; counter-increment: page;
@top-center { @top-center {
font-family: sans-serif; font-family: sans-serif;
font-weight: bold; font-weight: bold;
font-size: 2em; font-size: 2em;
...@@ -145,27 +147,27 @@ li.last { ...@@ -145,27 +147,27 @@ li.last {
} }
} }
</textarea></p> </textarea></p>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code-js"), { var editor = CodeMirror.fromTextArea(document.getElementById("code-js"), {
lineNumbers: true, lineNumbers: true,
mode: "javascript", mode: "javascript",
gutters: ["CodeMirror-lint-markers"], gutters: ["CodeMirror-lint-markers"],
lint: true lint: true
}); });
var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), { var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), {
lineNumbers: true, lineNumbers: true,
mode: "application/json", mode: "application/json",
gutters: ["CodeMirror-lint-markers"], gutters: ["CodeMirror-lint-markers"],
lint: true lint: true
}); });
var editor_css = CodeMirror.fromTextArea(document.getElementById("code-css"), { var editor_css = CodeMirror.fromTextArea(document.getElementById("code-css"), {
lineNumbers: true, lineNumbers: true,
mode: "css", mode: "css",
gutters: ["CodeMirror-lint-markers"], gutters: ["CodeMirror-lint-markers"],
lint: true lint: true
}); });
</script> </script>
</article> </article>
...@@ -2,15 +2,18 @@ ...@@ -2,15 +2,18 @@
<title>CodeMirror: Lazy Mode Loading Demo</title> <title>CodeMirror: Lazy Mode Loading Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/mode/loadmode.js"></script> <script src="../addon/mode/loadmode.js"></script>
<script src="../mode/meta.js"></script> <script src="../mode/meta.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
</style> border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -25,48 +28,51 @@ ...@@ -25,48 +28,51 @@
</div> </div>
<article> <article>
<h2>Lazy Mode Loading Demo</h2> <h2>Lazy Mode Loading Demo</h2>
<p style="color: gray">Current mode: <span id="modeinfo">text/plain</span></p> <p style="color: gray">Current mode: <span id="modeinfo">text/plain</span></p>
<form><textarea id="code" name="code">This is the editor. <form><textarea id="code" name="code">This is the editor.
// It starts out in plain text mode, // It starts out in plain text mode,
# use the control below to load and apply a mode # use the control below to load and apply a mode
"you'll see the highlighting of" this text /*change*/. "you'll see the highlighting of" this text /*change*/.
</textarea></form> </textarea></form>
<p>Filename, mime, or mode name: <input type=text value=foo.js id=mode> <button type=button onclick="change()">change mode</button></p> <p>Filename, mime, or mode name: <input id=mode type=text value=foo.js>
<button onclick="change()" type=button>change mode</button>
</p>
<script> <script>
CodeMirror.modeURL = "../mode/%N/%N.js"; CodeMirror.modeURL = "../mode/%N/%N.js";
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true lineNumbers: true
}); });
var modeInput = document.getElementById("mode"); var modeInput = document.getElementById("mode");
CodeMirror.on(modeInput, "keypress", function(e) { CodeMirror.on(modeInput, "keypress", function (e) {
if (e.keyCode == 13) change(); if (e.keyCode == 13) change();
}); });
function change() {
var val = modeInput.value, m, mode, spec; function change() {
if (m = /.+\.([^.]+)$/.exec(val)) { var val = modeInput.value, m, mode, spec;
var info = CodeMirror.findModeByExtension(m[1]); if (m = /.+\.([^.]+)$/.exec(val)) {
if (info) { var info = CodeMirror.findModeByExtension(m[1]);
mode = info.mode; if (info) {
spec = info.mime; mode = info.mode;
} spec = info.mime;
} else if (/\//.test(val)) { }
var info = CodeMirror.findModeByMIME(val); } else if (/\//.test(val)) {
if (info) { var info = CodeMirror.findModeByMIME(val);
mode = info.mode; if (info) {
spec = val; mode = info.mode;
spec = val;
}
} else {
mode = spec = val;
}
if (mode) {
editor.setOption("mode", spec);
CodeMirror.autoLoadMode(editor, mode);
document.getElementById("modeinfo").textContent = spec;
} else {
alert("Could not find a mode corresponding to " + val);
}
} }
} else { </script>
mode = spec = val; </article>
}
if (mode) {
editor.setOption("mode", spec);
CodeMirror.autoLoadMode(editor, mode);
document.getElementById("modeinfo").textContent = spec;
} else {
alert("Could not find a mode corresponding to " + val);
}
}
</script>
</article>
...@@ -2,16 +2,24 @@ ...@@ -2,16 +2,24 @@
<title>CodeMirror: Breakpoint Demo</title> <title>CodeMirror: Breakpoint Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script> <script src="../mode/javascript/javascript.js"></script>
<style> <style>
.breakpoints {width: .8em;} .breakpoints {
.breakpoint { color: #822; } width: .8em;
.CodeMirror {border: 1px solid #aaa;} }
</style>
.breakpoint {
color: #822;
}
.CodeMirror {
border: 1px solid #aaa;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -26,27 +34,27 @@ ...@@ -26,27 +34,27 @@
</div> </div>
<article> <article>
<h2>Breakpoint Demo</h2> <h2>Breakpoint Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
gutters: ["CodeMirror-linenumbers", "breakpoints"] gutters: ["CodeMirror-linenumbers", "breakpoints"]
}); });
editor.on("gutterClick", function(cm, n) { editor.on("gutterClick", function(cm, n) {
var info = cm.lineInfo(n); var info = cm.lineInfo(n);
cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker()); cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker());
}); });
function makeMarker() { function makeMarker() {
var marker = document.createElement("div"); var marker = document.createElement("div");
marker.style.color = "#822"; marker.style.color = "#822";
marker.innerHTML = "●"; marker.innerHTML = "●";
return marker; return marker;
} }
</textarea></form> </textarea></form>
<p>Click the line-number gutter to add or remove 'breakpoints'.</p> <p>Click the line-number gutter to add or remove 'breakpoints'.</p>
<script>eval(document.getElementById("code").value);</script> <script>eval(document.getElementById("code").value);</script>
</article> </article>
...@@ -2,18 +2,30 @@ ...@@ -2,18 +2,30 @@
<title>CodeMirror: Selection Marking Demo</title> <title>CodeMirror: Selection Marking Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/search/searchcursor.js"></script> <script src="../addon/search/searchcursor.js"></script>
<script src="../addon/selection/mark-selection.js"></script> <script src="../addon/selection/mark-selection.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
.CodeMirror-selected { background-color: blue !important; } border-top: 1px solid black;
.CodeMirror-selectedtext { color: white; } border-bottom: 1px solid black;
.styled-background { background-color: #ff7; } }
</style>
.CodeMirror-selected {
background-color: blue !important;
}
.CodeMirror-selectedtext {
color: white;
}
.styled-background {
background-color: #ff7;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -28,8 +40,8 @@ ...@@ -28,8 +40,8 @@
</div> </div>
<article> <article>
<h2>Selection Marking Demo</h2> <h2>Selection Marking Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
Select something from here. You'll see that the selection's foreground Select something from here. You'll see that the selection's foreground
color changes to white! Since, by default, CodeMirror only puts an color changes to white! Since, by default, CodeMirror only puts an
independent "marker" layer behind the text, you'll need something like independent "marker" layer behind the text, you'll need something like
...@@ -39,14 +51,15 @@ Also notice that turning this addon on (with the default style) allows ...@@ -39,14 +51,15 @@ Also notice that turning this addon on (with the default style) allows
you to safely give text a background color without screwing up the you to safely give text a background color without screwing up the
visibility of the selection.</textarea></form> visibility of the selection.</textarea></form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
styleSelectedText: true styleSelectedText: true
}); });
editor.markText({line: 6, ch: 26}, {line: 6, ch: 42}, {className: "styled-background"}); editor.markText({line: 6, ch: 26}, {line: 6, ch: 42}, {className: "styled-background"});
</script> </script>
<p>Simple addon to easily mark (and style) selected text. <a href="../doc/manual.html#addon_mark-selection">Docs</a>.</p> <p>Simple addon to easily mark (and style) selected text. <a href="../doc/manual.html#addon_mark-selection">Docs</a>.
</p>
</article> </article>
...@@ -2,24 +2,34 @@ ...@@ -2,24 +2,34 @@
<title>CodeMirror: Match Highlighter Demo</title> <title>CodeMirror: Match Highlighter Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/scroll/annotatescrollbar.js"></script> <script src="../addon/scroll/annotatescrollbar.js"></script>
<script src="../addon/search/matchesonscrollbar.js"></script> <script src="../addon/search/matchesonscrollbar.js"></script>
<script src="../addon/search/searchcursor.js"></script> <script src="../addon/search/searchcursor.js"></script>
<script src="../addon/search/match-highlighter.js"></script> <script src="../addon/search/match-highlighter.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
.CodeMirror-focused .cm-matchhighlight { border-top: 1px solid black;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==); border-bottom: 1px solid black;
background-position: bottom; }
background-repeat: repeat-x;
} .CodeMirror-focused .cm-matchhighlight {
.cm-matchhighlight {background-color: lightgreen} background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
.CodeMirror-selection-highlight-scrollbar {background-color: green} background-position: bottom;
</style> background-repeat: repeat-x;
}
.cm-matchhighlight {
background-color: lightgreen
}
.CodeMirror-selection-highlight-scrollbar {
background-color: green
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -34,8 +44,8 @@ ...@@ -34,8 +44,8 @@
</div> </div>
<article> <article>
<h2>Match Highlighter Demo</h2> <h2>Match Highlighter Demo</h2>
<form><textarea id="code" name="code">Select this text: hardtospot <form><textarea id="code" name="code">Select this text: hardtospot
And everywhere else in your code where hardtospot appears will And everywhere else in your code where hardtospot appears will
automatically illuminate. Give it a try! No more hard to spot automatically illuminate. Give it a try! No more hard to spot
variables - stay in context of your code all the time. variables - stay in context of your code all the time.
...@@ -89,15 +99,15 @@ ornare accumsan. In hac habitasse hardtospot platea dictumst. ...@@ -89,15 +99,15 @@ ornare accumsan. In hac habitasse hardtospot platea dictumst.
</textarea></form> </textarea></form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
// To highlight on scrollbars as well, pass annotateScrollbar in options // To highlight on scrollbars as well, pass annotateScrollbar in options
// as below. // as below.
highlightSelectionMatches: {showToken: /\w/, annotateScrollbar: true} highlightSelectionMatches: {showToken: /\w/, annotateScrollbar: true}
}); });
</script> </script>
<p>Search and highlight occurences of the selected text.</p> <p>Search and highlight occurences of the selected text.</p>
</article> </article>
...@@ -2,16 +2,19 @@ ...@@ -2,16 +2,19 @@
<title>CodeMirror: Tag Matcher Demo</title> <title>CodeMirror: Tag Matcher Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/fold/xml-fold.js"></script> <script src="../addon/fold/xml-fold.js"></script>
<script src="../addon/edit/matchtags.js"></script> <script src="../addon/edit/matchtags.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
</style> border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -26,23 +29,23 @@ ...@@ -26,23 +29,23 @@
</div> </div>
<article> <article>
<h2>Tag Matcher Demo</h2> <h2>Tag Matcher Demo</h2>
<div id="editor"></div> <div id="editor"></div>
<script> <script>
window.onload = function() { window.onload = function () {
editor = CodeMirror(document.getElementById("editor"), { editor = CodeMirror(document.getElementById("editor"), {
value: "<html>\n " + document.documentElement.innerHTML + "\n</html>", value: "<html>\n " + document.documentElement.innerHTML + "\n</html>",
mode: "text/html", mode: "text/html",
matchTags: {bothTags: true}, matchTags: {bothTags: true},
extraKeys: {"Ctrl-J": "toMatchingTag"} extraKeys: {"Ctrl-J": "toMatchingTag"}
}); });
}; };
</script> </script>
<p>Put the cursor on or inside a pair of tags to highlight them. <p>Put the cursor on or inside a pair of tags to highlight them.
Press Ctrl-J to jump to the tag that matches the one under the Press Ctrl-J to jump to the tag that matches the one under the
cursor.</p> cursor.</p>
</article> </article>
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<title>CodeMirror: merge view demo</title> <title>CodeMirror: merge view demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel=stylesheet href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel=stylesheet>
<link rel=stylesheet href="../addon/merge/merge.css"> <link href="../addon/merge/merge.css" rel=stylesheet>
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<script src="../mode/css/css.js"></script> <script src="../mode/css/css.js"></script>
...@@ -14,19 +14,28 @@ ...@@ -14,19 +14,28 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"></script>
<script src="../addon/merge/merge.js"></script> <script src="../addon/merge/merge.js"></script>
<style> <style>
.CodeMirror { line-height: 1.2; } .CodeMirror {
@media screen and (min-width: 1300px) { line-height: 1.2;
article { max-width: 1000px; } }
#nav { border-right: 499px solid transparent; }
@media screen and (min-width: 1300px) {
article {
max-width: 1000px;
} }
span.clicky {
cursor: pointer; #nav {
background: #d70; border-right: 499px solid transparent;
color: white;
padding: 0 3px;
border-radius: 3px;
} }
</style> }
span.clicky {
cursor: pointer;
background: #d70;
color: white;
padding: 0 3px;
border-radius: 3px;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -41,83 +50,87 @@ ...@@ -41,83 +50,87 @@
</div> </div>
<article> <article>
<h2>merge view demo</h2> <h2>merge view demo</h2>
<div id=view></div> <div id=view></div>
<p>The <a href="../doc/manual.html#addon_merge"><code>merge</code></a> <p>The <a href="../doc/manual.html#addon_merge"><code>merge</code></a>
addon provides an interface for displaying and merging diffs, addon provides an interface for displaying and merging diffs,
either <span class=clicky onclick="panes = 2; initUI()">two-way</span> either <span class=clicky onclick="panes = 2; initUI()">two-way</span>
or <span class=clicky onclick="panes = 3; initUI()">three-way</span>. or <span class=clicky onclick="panes = 3; initUI()">three-way</span>.
The left (or center) pane is editable, and the differences with the The left (or center) pane is editable, and the differences with the
other pane(s) are <span class=clicky other pane(s) are <span class=clicky
onclick="toggleDifferences()">optionally</span> shown live as you edit onclick="toggleDifferences()">optionally</span> shown live as you edit
it. In the two-way configuration, there are also options to pad changed it. In the two-way configuration, there are also options to pad changed
sections to <span class=clicky onclick="connect = connect ? null : sections to <span class=clicky onclick="connect = connect ? null :
'align'; initUI()">align</span> them, and to <span class=clicky 'align'; initUI()">align</span> them, and to <span class=clicky
onclick="collapse = !collapse; initUI()">collapse</span> unchanged onclick="collapse = !collapse; initUI()">collapse</span> unchanged
stretches of text.</p> stretches of text.</p>
<p>This addon depends on <p>This addon depends on
the <a href="https://code.google.com/p/google-diff-match-patch/">google-diff-match-patch</a> the <a href="https://code.google.com/p/google-diff-match-patch/">google-diff-match-patch</a>
library to compute the diffs.</p> library to compute the diffs.</p>
<script> <script>
var value, orig1, orig2, dv, panes = 2, highlight = true, connect = "align", collapse = false; var value, orig1, orig2, dv, panes = 2, highlight = true, connect = "align", collapse = false;
function initUI() {
if (value == null) return; function initUI() {
var target = document.getElementById("view"); if (value == null) return;
target.innerHTML = ""; var target = document.getElementById("view");
dv = CodeMirror.MergeView(target, { target.innerHTML = "";
value: value, dv = CodeMirror.MergeView(target, {
origLeft: panes == 3 ? orig1 : null, value: value,
orig: orig2, origLeft: panes == 3 ? orig1 : null,
lineNumbers: true, orig: orig2,
mode: "text/html", lineNumbers: true,
highlightDifferences: highlight, mode: "text/html",
connect: connect, highlightDifferences: highlight,
collapseIdentical: collapse connect: connect,
}); collapseIdentical: collapse
} });
}
function toggleDifferences() {
dv.setShowDifferences(highlight = !highlight); function toggleDifferences() {
} dv.setShowDifferences(highlight = !highlight);
}
window.onload = function() {
value = document.documentElement.innerHTML; window.onload = function () {
orig1 = "<!doctype html>\n\n" + value.replace(/\.\.\//g, "codemirror/").replace("yellow", "orange"); value = document.documentElement.innerHTML;
orig2 = value.replace(/\u003cscript/g, "\u003cscript type=text/javascript ") orig1 = "<!doctype html>\n\n" + value.replace(/\.\.\//g, "codemirror/").replace("yellow", "orange");
.replace("white", "purple;\n font: comic sans;\n text-decoration: underline;\n height: 15em"); orig2 = value.replace(/\u003cscript/g, "\u003cscript type=text/javascript ")
initUI(); .replace("white", "purple;\n font: comic sans;\n text-decoration: underline;\n height: 15em");
let d = document.createElement("div"); d.style.cssText = "width: 50px; margin: 7px; height: 14px"; dv.editor().addLineWidget(57, d) initUI();
}; let d = document.createElement("div");
d.style.cssText = "width: 50px; margin: 7px; height: 14px";
function mergeViewHeight(mergeView) { dv.editor().addLineWidget(57, d)
function editorHeight(editor) { };
if (!editor) return 0;
return editor.getScrollInfo().height; function mergeViewHeight(mergeView) {
} function editorHeight(editor) {
return Math.max(editorHeight(mergeView.leftOriginal()), if (!editor) return 0;
editorHeight(mergeView.editor()), return editor.getScrollInfo().height;
editorHeight(mergeView.rightOriginal())); }
}
return Math.max(editorHeight(mergeView.leftOriginal()),
function resize(mergeView) { editorHeight(mergeView.editor()),
var height = mergeViewHeight(mergeView); editorHeight(mergeView.rightOriginal()));
for(;;) { }
if (mergeView.leftOriginal())
mergeView.leftOriginal().setSize(null, height); function resize(mergeView) {
mergeView.editor().setSize(null, height); var height = mergeViewHeight(mergeView);
if (mergeView.rightOriginal()) for (; ;) {
mergeView.rightOriginal().setSize(null, height); if (mergeView.leftOriginal())
mergeView.leftOriginal().setSize(null, height);
var newHeight = mergeViewHeight(mergeView); mergeView.editor().setSize(null, height);
if (newHeight >= height) break; if (mergeView.rightOriginal())
else height = newHeight; mergeView.rightOriginal().setSize(null, height);
}
mergeView.wrap.style.height = height + "px"; var newHeight = mergeViewHeight(mergeView);
} if (newHeight >= height) break;
</script> else height = newHeight;
}
mergeView.wrap.style.height = height + "px";
}
</script>
</article> </article>
...@@ -2,16 +2,21 @@ ...@@ -2,16 +2,21 @@
<title>CodeMirror: Multiplexing Parser Demo</title> <title>CodeMirror: Multiplexing Parser Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/mode/multiplex.js"></script> <script src="../addon/mode/multiplex.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<style> <style>
.CodeMirror {border: 1px solid black;} .CodeMirror {
.cm-delimit {color: #fa4;} border: 1px solid black;
</style> }
.cm-delimit {
color: #fa4;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -26,11 +31,11 @@ ...@@ -26,11 +31,11 @@
</div> </div>
<article> <article>
<h2>Multiplexing Parser Demo</h2> <h2>Multiplexing Parser Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
<html> <html>
<body style="<<magic>>"> <body style="<<magic>>">
<h1><< this is not <html >></h1> <h1><< this is not <html>></h1>
<< <<
multiline multiline
not html not html
...@@ -41,35 +46,37 @@ ...@@ -41,35 +46,37 @@
</html> </html>
</textarea></form> </textarea></form>
<script> <script>
CodeMirror.defineMode("demo", function(config) { CodeMirror.defineMode("demo", function (config) {
return CodeMirror.multiplexingMode( return CodeMirror.multiplexingMode(
CodeMirror.getMode(config, "text/html"), CodeMirror.getMode(config, "text/html"),
{open: "<<", close: ">>", {
mode: CodeMirror.getMode(config, "text/plain"), open: "<<", close: ">>",
delimStyle: "delimit"} mode: CodeMirror.getMode(config, "text/plain"),
// .. more multiplexed styles can follow here delimStyle: "delimit"
); }
}); // .. more multiplexed styles can follow here
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { );
mode: "demo", });
lineNumbers: true, var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineWrapping: true mode: "demo",
}); lineNumbers: true,
</script> lineWrapping: true
});
</script>
<p>Demonstration of a multiplexing mode, which, at certain <p>Demonstration of a multiplexing mode, which, at certain
boundary strings, switches to one or more inner modes. The out boundary strings, switches to one or more inner modes. The out
(HTML) mode does not get fed the content of the <code>&lt;&lt; (HTML) mode does not get fed the content of the <code>&lt;&lt;
>></code> blocks. See >></code> blocks. See
the <a href="../doc/manual.html#addon_multiplex">manual</a> and the <a href="../doc/manual.html#addon_multiplex">manual</a> and
the <a href="../addon/mode/multiplex.js">source</a> for more the <a href="../addon/mode/multiplex.js">source</a> for more
information.</p> information.</p>
<p> <p>
<strong>Parsing/Highlighting Tests:</strong> <strong>Parsing/Highlighting Tests:</strong>
<a href="../test/index.html#multiplexing_*">normal</a>, <a href="../test/index.html#multiplexing_*">normal</a>,
<a href="../test/index.html#verbose,multiplexing_*">verbose</a>. <a href="../test/index.html#verbose,multiplexing_*">verbose</a>.
</p> </p>
</article> </article>
...@@ -2,15 +2,20 @@ ...@@ -2,15 +2,20 @@
<title>CodeMirror: Overlay Parser Demo</title> <title>CodeMirror: Overlay Parser Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/mode/overlay.js"></script> <script src="../addon/mode/overlay.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<style> <style>
.CodeMirror {border: 1px solid black;} .CodeMirror {
.cm-mustache {color: #0ca;} border: 1px solid black;
}
.cm-mustache {
color: #0ca;
}
</style> </style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -26,44 +31,45 @@ ...@@ -26,44 +31,45 @@
</div> </div>
<article> <article>
<h2>Overlay Parser Demo</h2> <h2>Overlay Parser Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
<html> <html>
<body> <body>
<h1>{{title}}</h1> <h1>{{title}}</h1>
<p>These are links to {{things}}:</p> <p>These are links to {{things}}:</p>
<ul>{{#links}} <ul>{{#links}}
<li><a href="{{url}}">{{text}}</a></li> <li><a href="{{url}}">{{text}}</a></li>
{{/links}}</ul> {{/links}}</ul>
</body> </body>
</html> </html>
</textarea></form> </textarea></form>
<script> <script>
CodeMirror.defineMode("mustache", function(config, parserConfig) { CodeMirror.defineMode("mustache", function (config, parserConfig) {
var mustacheOverlay = { var mustacheOverlay = {
token: function(stream, state) { token: function (stream, state) {
var ch; var ch;
if (stream.match("{{")) { if (stream.match("{{")) {
while ((ch = stream.next()) != null) while ((ch = stream.next()) != null)
if (ch == "}" && stream.next() == "}") { if (ch == "}" && stream.next() == "}") {
stream.eat("}"); stream.eat("}");
return "mustache"; return "mustache";
}
}
while (stream.next() != null && !stream.match("{{", false)) {
} }
} return null;
while (stream.next() != null && !stream.match("{{", false)) {} }
return null; };
} return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
}; });
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay); var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "mustache"});
}); </script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "mustache"});
</script>
<p>Demonstration of a mode that parses HTML, highlighting <p>Demonstration of a mode that parses HTML, highlighting
the <a href="http://mustache.github.com/">Mustache</a> templating the <a href="http://mustache.github.com/">Mustache</a> templating
directives inside of it by using the code directives inside of it by using the code
in <a href="../addon/mode/overlay.js"><code>overlay.js</code></a>. View in <a href="../addon/mode/overlay.js"><code>overlay.js</code></a>. View
source to see the 15 lines of code needed to accomplish this.</p> source to see the 15 lines of code needed to accomplish this.</p>
</article> </article>
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
<title>CodeMirror: Panel Demo</title> <title>CodeMirror: Panel Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script> <script src="../mode/javascript/javascript.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
...@@ -14,26 +14,32 @@ ...@@ -14,26 +14,32 @@
.border { .border {
border: 1px solid #f7f7f7; border: 1px solid #f7f7f7;
} }
.add-panel { .add-panel {
background: orange; background: orange;
padding: 3px 6px; padding: 3px 6px;
color: white !important; color: white !important;
border-radius: 3px; border-radius: 3px;
} }
.add-panel, .remove-panel { .add-panel, .remove-panel {
cursor: pointer; cursor: pointer;
} }
.remove-panel { .remove-panel {
float: right; float: right;
} }
.panel { .panel {
background: #f7f7f7; background: #f7f7f7;
padding: 3px 7px; padding: 3px 7px;
font-size: 0.85em; font-size: 0.85em;
} }
.panel.top, .panel.after-top { .panel.top, .panel.after-top {
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
} }
.panel.bottom, .panel.before-bottom { .panel.bottom, .panel.before-bottom {
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
} }
...@@ -54,84 +60,85 @@ ...@@ -54,84 +60,85 @@
<article> <article>
<h2>Panel Demo</h2> <h2>Panel Demo</h2>
<div class="border"> <div class="border">
<textarea id="code" name="code"></textarea> <textarea id="code" name="code"></textarea>
</div> </div>
<p> <p>
The <a href="../doc/manual.html#addon_panel"><code>panel</code></a> The <a href="../doc/manual.html#addon_panel"><code>panel</code></a>
addon allows you to display panels above or below an editor. addon allows you to display panels above or below an editor.
<br> <br>
Click the links below to add panels at the given position: Click the links below to add panels at the given position:
</p> </p>
<div id="demo"> <div id="demo">
<p> <p>
<a class="add-panel" onclick="addPanel('top')">top</a> <a class="add-panel" onclick="addPanel('top')">top</a>
<a class="add-panel" onclick="addPanel('after-top')">after-top</a> <a class="add-panel" onclick="addPanel('after-top')">after-top</a>
<a class="add-panel" onclick="addPanel('before-bottom')">before-bottom</a> <a class="add-panel" onclick="addPanel('before-bottom')">before-bottom</a>
<a class="add-panel" onclick="addPanel('bottom')">bottom</a> <a class="add-panel" onclick="addPanel('bottom')">bottom</a>
</p> </p>
<p> <p>
You can also replace an existing panel: You can also replace an existing panel:
</p> </p>
<form onsubmit="return replacePanel(this);" name="replace_panel"> <form name="replace_panel" onsubmit="return replacePanel(this);">
<input type="submit" value="Replace panel n°" /> <input type="submit" value="Replace panel n°"/>
<input type="number" name="panel_id" min="1" value="1" /> <input min="1" name="panel_id" type="number" value="1"/>
</form> </form>
<script> <script>
var textarea = document.getElementById("code"); var textarea = document.getElementById("code");
var demo = document.getElementById("demo"); var demo = document.getElementById("demo");
var numPanels = 0; var numPanels = 0;
var panels = {}; var panels = {};
var editor; var editor;
textarea.value = demo.innerHTML.trim(); textarea.value = demo.innerHTML.trim();
editor = CodeMirror.fromTextArea(textarea, { editor = CodeMirror.fromTextArea(textarea, {
lineNumbers: true, lineNumbers: true,
mode: "htmlmixed" mode: "htmlmixed"
}); });
function makePanel(where) { function makePanel(where) {
var node = document.createElement("div"); var node = document.createElement("div");
var id = ++numPanels; var id = ++numPanels;
var widget, close, label; var widget, close, label;
node.id = "panel-" + id; node.id = "panel-" + id;
node.className = "panel " + where; node.className = "panel " + where;
close = node.appendChild(document.createElement("a")); close = node.appendChild(document.createElement("a"));
close.setAttribute("title", "Remove me!"); close.setAttribute("title", "Remove me!");
close.setAttribute("class", "remove-panel"); close.setAttribute("class", "remove-panel");
close.textContent = ""; close.textContent = "";
CodeMirror.on(close, "mousedown", function(e) { CodeMirror.on(close, "mousedown", function (e) {
e.preventDefault() e.preventDefault()
panels[node.id].clear(); panels[node.id].clear();
}); });
label = node.appendChild(document.createElement("span")); label = node.appendChild(document.createElement("span"));
label.textContent = "I'm panel n°" + id; label.textContent = "I'm panel n°" + id;
return node; return node;
} }
function addPanel(where) {
var node = makePanel(where); function addPanel(where) {
panels[node.id] = editor.addPanel(node, {position: where, stable: true}); var node = makePanel(where);
} panels[node.id] = editor.addPanel(node, {position: where, stable: true});
}
addPanel("top");
addPanel("bottom"); addPanel("top");
addPanel("bottom");
function replacePanel(form) {
var id = form.elements.panel_id.value; function replacePanel(form) {
var panel = panels["panel-" + id]; var id = form.elements.panel_id.value;
var node = makePanel(""); var panel = panels["panel-" + id];
var node = makePanel("");
panels[node.id] = editor.addPanel(node, {replace: panel, position: "after-top", stable: true});
return false; panels[node.id] = editor.addPanel(node, {replace: panel, position: "after-top", stable: true});
} return false;
</script> }
</script>
</div>
</div>
</article> </article>
...@@ -2,17 +2,28 @@ ...@@ -2,17 +2,28 @@
<title>CodeMirror: Placeholder demo</title> <title>CodeMirror: Placeholder demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/display/placeholder.js"></script> <script src="../addon/display/placeholder.js"></script>
<style> <style>
.CodeMirror { border: 1px solid silver; } .CodeMirror {
.CodeMirror-empty { outline: 1px solid #c22; } border: 1px solid silver;
.CodeMirror-empty.CodeMirror-focused { outline: none; } }
.CodeMirror pre.CodeMirror-placeholder { color: #999; }
</style> .CodeMirror-empty {
outline: 1px solid #c22;
}
.CodeMirror-empty.CodeMirror-focused {
outline: none;
}
.CodeMirror pre.CodeMirror-placeholder {
color: #999;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -27,19 +38,19 @@ ...@@ -27,19 +38,19 @@
</div> </div>
<article> <article>
<h2>Placeholder demo</h2> <h2>Placeholder demo</h2>
<form><textarea id="code" name="code" placeholder="Code goes here..."></textarea></form> <form><textarea id="code" name="code" placeholder="Code goes here..."></textarea></form>
<p>The <a href="../doc/manual.html#addon_placeholder">placeholder</a> <p>The <a href="../doc/manual.html#addon_placeholder">placeholder</a>
plug-in adds an option <code>placeholder</code> that can be set to plug-in adds an option <code>placeholder</code> that can be set to
make text appear in the editor when it is empty and not focused. make text appear in the editor when it is empty and not focused.
If the source textarea has a <code>placeholder</code> attribute, If the source textarea has a <code>placeholder</code> attribute,
it will automatically be inherited.</p> it will automatically be inherited.</p>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true lineNumbers: true
}); });
</script> </script>
</article> </article>
...@@ -2,28 +2,29 @@ ...@@ -2,28 +2,29 @@
<title>CodeMirror: HTML5 preview</title> <title>CodeMirror: HTML5 preview</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel=stylesheet href=../lib/codemirror.css> <link href=../lib/codemirror.css rel=stylesheet>
<script src=../lib/codemirror.js></script> <script src=../lib/codemirror.js></script>
<script src=../mode/xml/xml.js></script> <script src=../mode/xml/xml.js></script>
<script src=../mode/javascript/javascript.js></script> <script src=../mode/javascript/javascript.js></script>
<script src=../mode/css/css.js></script> <script src=../mode/css/css.js></script>
<script src=../mode/htmlmixed/htmlmixed.js></script> <script src=../mode/htmlmixed/htmlmixed.js></script>
<style type=text/css> <style type=text/css>
.CodeMirror { .CodeMirror {
float: left; float: left;
width: 50%; width: 50%;
border: 1px solid black; border: 1px solid black;
} }
iframe {
width: 49%; iframe {
float: left; width: 49%;
height: 300px; float: left;
border: 1px solid black; height: 300px;
border-left: 0px; border: 1px solid black;
} border-left: 0px;
</style> }
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -38,19 +39,21 @@ ...@@ -38,19 +39,21 @@
</div> </div>
<article> <article>
<h2>HTML5 preview</h2> <h2>HTML5 preview</h2>
<textarea id=code name=code> <textarea id=code name=code>
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<meta charset=utf-8> <meta charset=utf-8>
<title>HTML5 canvas demo</title> <title>HTML5 canvas demo</title>
<style>p {font-family: monospace;}</style> <style>p {
font-family: monospace;
}</style>
</head> </head>
<body> <body>
<p>Canvas pane goes here:</p> <p>Canvas pane goes here:</p>
<canvas id=pane width=300 height=200></canvas> <canvas height=200 id=pane width=300></canvas>
<script> <script>
var canvas = document.getElementById('pane'); var canvas = document.getElementById('pane');
var context = canvas.getContext('2d'); var context = canvas.getContext('2d');
...@@ -63,25 +66,26 @@ ...@@ -63,25 +66,26 @@
</script> </script>
</body> </body>
</html></textarea> </html></textarea>
<iframe id=preview></iframe> <iframe id=preview></iframe>
<script> <script>
var delay; var delay;
// Initialize CodeMirror editor with a nice html5 canvas demo. // Initialize CodeMirror editor with a nice html5 canvas demo.
var editor = CodeMirror.fromTextArea(document.getElementById('code'), { var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
mode: 'text/html' mode: 'text/html'
}); });
editor.on("change", function() { editor.on("change", function () {
clearTimeout(delay); clearTimeout(delay);
delay = setTimeout(updatePreview, 300); delay = setTimeout(updatePreview, 300);
}); });
function updatePreview() { function updatePreview() {
var previewFrame = document.getElementById('preview'); var previewFrame = document.getElementById('preview');
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document; var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
preview.open(); preview.open();
preview.write(editor.getValue()); preview.write(editor.getValue());
preview.close(); preview.close();
} }
setTimeout(updatePreview, 300);
</script> setTimeout(updatePreview, 300);
</article> </script>
</article>
...@@ -3,68 +3,71 @@ ...@@ -3,68 +3,71 @@
<head> <head>
<title>CodeMirror: HTML completion demo</title> <title>CodeMirror: HTML completion demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/hint/show-hint.css"> <link href="../addon/hint/show-hint.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.min.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;} .CodeMirror {
border-top: 1px solid #888;
border-bottom: 1px solid #888;
}
</style> </style>
</head> </head>
<body> <body>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
<ul> <ul>
<li><a href="../index.html">Home</a> <li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a> <li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a> <li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul> </ul>
<ul> <ul>
<li><a class=active href="#">HTML completion</a> <li><a class=active href="#">HTML completion</a>
</ul> </ul>
</div> </div>
<article> <article>
<h2>RequireJS module loading demo</h2> <h2>RequireJS module loading demo</h2>
<p>This demo does the same thing as <p>This demo does the same thing as
the <a href="html5complete.html">HTML5 completion demo</a>, but the <a href="html5complete.html">HTML5 completion demo</a>, but
loads its dependencies loads its dependencies
with <a href="http://requirejs.org/">Require.js</a>, rather than with <a href="http://requirejs.org/">Require.js</a>, rather than
explicitly. Press <strong>ctrl-space</strong> to activate explicitly. Press <strong>ctrl-space</strong> to activate
completion.</p> completion.</p>
<div id="code"></div> <div id="code"></div>
<button id="markdown">Dynamically load Markdown mode</button> <button id="markdown">Dynamically load Markdown mode</button>
<script> <script>
require.config({ require.config({
packages: [{ packages: [{
name: "codemirror", name: "codemirror",
location: "../", location: "../",
main: "lib/codemirror" main: "lib/codemirror"
}] }]
});
require(["codemirror", "codemirror/mode/htmlmixed/htmlmixed",
"codemirror/addon/hint/show-hint", "codemirror/addon/hint/html-hint",
"codemirror/addon/mode/loadmode"], function (CodeMirror) {
editor = CodeMirror(document.getElementById("code"), {
mode: "text/html",
extraKeys: {"Ctrl-Space": "autocomplete"},
value: document.documentElement.innerHTML
}); });
require(["codemirror", "codemirror/mode/htmlmixed/htmlmixed",
"codemirror/addon/hint/show-hint", "codemirror/addon/hint/html-hint",
"codemirror/addon/mode/loadmode"], function(CodeMirror) {
editor = CodeMirror(document.getElementById("code"), {
mode: "text/html",
extraKeys: {"Ctrl-Space": "autocomplete"},
value: document.documentElement.innerHTML
});
CodeMirror.modeURL = "codemirror/mode/%N/%N"; CodeMirror.modeURL = "codemirror/mode/%N/%N";
document.getElementById("markdown").addEventListener("click", function() { document.getElementById("markdown").addEventListener("click", function () {
CodeMirror.requireMode("markdown", function() { CodeMirror.requireMode("markdown", function () {
editor.replaceRange("This is **Markdown**.\n\n", {line: 0, ch: 0}); editor.replaceRange("This is **Markdown**.\n\n", {line: 0, ch: 0});
editor.setOption("mode", "markdown"); editor.setOption("mode", "markdown");
});
}); });
}); });
</script> });
</article> </script>
</article>
</body> </body>
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
<title>CodeMirror: Autoresize Demo</title> <title>CodeMirror: Autoresize Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/css/css.js"></script> <script src="../mode/css/css.js"></script>
<style> <style>
.CodeMirror { .CodeMirror {
border: 1px solid #eee; border: 1px solid #eee;
height: auto; height: auto;
} }
</style> </style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -27,25 +27,25 @@ ...@@ -27,25 +27,25 @@
</div> </div>
<article> <article>
<h2>Autoresize Demo</h2> <h2>Autoresize Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
.CodeMirror { .CodeMirror {
border: 1px solid #eee; border: 1px solid #eee;
height: auto; height: auto;
} }
</textarea></form> </textarea></form>
<p>By setting an editor's <code>height</code> style <p>By setting an editor's <code>height</code> style
to <code>auto</code> and giving to <code>auto</code> and giving
the <a href="../doc/manual.html#option_viewportMargin"><code>viewportMargin</code></a> the <a href="../doc/manual.html#option_viewportMargin"><code>viewportMargin</code></a>
a value of <code>Infinity</code>, CodeMirror can be made to a value of <code>Infinity</code>, CodeMirror can be made to
automatically resize to fit its content.</p> automatically resize to fit its content.</p>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true, lineNumbers: true,
viewportMargin: Infinity viewportMargin: Infinity
}); });
</script> </script>
</article> </article>
...@@ -2,13 +2,16 @@ ...@@ -2,13 +2,16 @@
<title>CodeMirror: Ruler Demo</title> <title>CodeMirror: Ruler Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/display/rulers.js"></script> <script src="../addon/display/rulers.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;} .CodeMirror {
border-top: 1px solid #888;
border-bottom: 1px solid #888;
}
</style> </style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -24,26 +27,26 @@ ...@@ -24,26 +27,26 @@
</div> </div>
<article> <article>
<h2>Ruler Demo</h2> <h2>Ruler Demo</h2>
<script> <script>
var nums = "0123456789", space = " "; var nums = "0123456789", space = " ";
var colors = ["#fcc", "#f5f577", "#cfc", "#aff", "#ccf", "#fcf"]; var colors = ["#fcc", "#f5f577", "#cfc", "#aff", "#ccf", "#fcf"];
var rulers = [], value = ""; var rulers = [], value = "";
for (var i = 1; i <= 6; i++) { for (var i = 1; i <= 6; i++) {
rulers.push({color: colors[i], column: i * 10, lineStyle: "dashed"}); rulers.push({color: colors[i], column: i * 10, lineStyle: "dashed"});
for (var j = 1; j < i; j++) value += space; for (var j = 1; j < i; j++) value += space;
value += nums + "\n"; value += nums + "\n";
} }
var editor = CodeMirror(document.body.lastChild, { var editor = CodeMirror(document.body.lastChild, {
rulers: rulers, rulers: rulers,
value: value + value + value, value: value + value + value,
lineNumbers: true lineNumbers: true
}); });
</script> </script>
<p>Demonstration of <p>Demonstration of
the <a href="../doc/manual.html#addon_rulers">rulers</a> addon, which the <a href="../doc/manual.html#addon_rulers">rulers</a> addon, which
displays vertical lines at given column offsets.</p> displays vertical lines at given column offsets.</p>
</article> </article>
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
<title>CodeMirror: Mode Runner Demo</title> <title>CodeMirror: Mode Runner Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../addon/runmode/runmode-standalone.js"></script> <script src="../addon/runmode/runmode-standalone.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<div id=nav> <div id=nav>
...@@ -21,41 +21,43 @@ ...@@ -21,41 +21,43 @@
</div> </div>
<article> <article>
<h2>Mode Runner Demo</h2> <h2>Mode Runner Demo</h2>
<textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;"> <textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;">
<foobar> <foobar>
<blah>Enter your xml here and press the button below to display <blah>Enter your xml here and press the button below to display
it as highlighted by the CodeMirror XML mode</blah> it as highlighted by the CodeMirror XML mode</blah>
<tag2 foo="2" bar="&amp;quot;bar&amp;quot;"/> <tag2 bar="&amp;quot;bar&amp;quot;" foo="2"/>
</foobar></textarea><br> </foobar></textarea><br>
<button onclick="doHighlight();">Highlight!</button> <button onclick="doHighlight();">Highlight!</button>
<pre id="output" class="cm-s-default"></pre> <pre class="cm-s-default" id="output"></pre>
<script> <script>
function doHighlight() { function doHighlight() {
CodeMirror.runMode(document.getElementById("code").value, "application/xml", CodeMirror.runMode(document.getElementById("code").value, "application/xml",
document.getElementById("output")); document.getElementById("output"));
} }
</script> </script>
<p>Running a CodeMirror mode outside of the editor. <p>Running a CodeMirror mode outside of the editor.
The <code>CodeMirror.runMode</code> function, defined The <code>CodeMirror.runMode</code> function, defined
in <code><a href="../addon/runmode/runmode.js">addon/runmode/runmode.js</a></code> takes the following arguments:</p> in <code><a href="../addon/runmode/runmode.js">addon/runmode/runmode.js</a></code> takes the following arguments:
</p>
<dl>
<dt><code>text (string)</code></dt> <dl>
<dd>The document to run through the highlighter.</dd> <dt><code>text (string)</code></dt>
<dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt> <dd>The document to run through the highlighter.</dd>
<dd>The mode to use (must be loaded as normal).</dd> <dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt>
<dt><code>output (function or DOM node)</code></dt> <dd>The mode to use (must be loaded as normal).</dd>
<dd>If this is a function, it will be called for each token with <dt><code>output (function or DOM node)</code></dt>
<dd>If this is a function, it will be called for each token with
two arguments, the token's text and the token's style class (may two arguments, the token's text and the token's style class (may
be <code>null</code> for unstyled tokens). If it is a DOM node, be <code>null</code> for unstyled tokens). If it is a DOM node,
the tokens will be converted to <code>span</code> elements as in the tokens will be converted to <code>span</code> elements as in
an editor, and inserted into the node an editor, and inserted into the node
(through <code>innerHTML</code>).</dd> (through <code>innerHTML</code>).
</dl> </dd>
</dl>
</article> </article>
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
<title>CodeMirror: Mode Runner Demo</title> <title>CodeMirror: Mode Runner Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../addon/runmode/runmode.js"></script> <script src="../addon/runmode/runmode.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
...@@ -22,41 +22,43 @@ ...@@ -22,41 +22,43 @@
</div> </div>
<article> <article>
<h2>Mode Runner Demo</h2> <h2>Mode Runner Demo</h2>
<textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;"> <textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;">
<foobar> <foobar>
<blah>Enter your xml here and press the button below to display <blah>Enter your xml here and press the button below to display
it as highlighted by the CodeMirror XML mode</blah> it as highlighted by the CodeMirror XML mode</blah>
<tag2 foo="2" bar="&amp;quot;bar&amp;quot;"/> <tag2 bar="&amp;quot;bar&amp;quot;" foo="2"/>
</foobar></textarea><br> </foobar></textarea><br>
<button onclick="doHighlight();">Highlight!</button> <button onclick="doHighlight();">Highlight!</button>
<pre id="output" class="cm-s-default"></pre> <pre class="cm-s-default" id="output"></pre>
<script> <script>
function doHighlight() { function doHighlight() {
CodeMirror.runMode(document.getElementById("code").value, "application/xml", CodeMirror.runMode(document.getElementById("code").value, "application/xml",
document.getElementById("output")); document.getElementById("output"));
} }
</script> </script>
<p>Running a CodeMirror mode outside of the editor. <p>Running a CodeMirror mode outside of the editor.
The <code>CodeMirror.runMode</code> function, defined The <code>CodeMirror.runMode</code> function, defined
in <code><a href="../addon/runmode/runmode.js">addon/runmode/runmode.js</a></code> takes the following arguments:</p> in <code><a href="../addon/runmode/runmode.js">addon/runmode/runmode.js</a></code> takes the following arguments:
</p>
<dl>
<dt><code>text (string)</code></dt> <dl>
<dd>The document to run through the highlighter.</dd> <dt><code>text (string)</code></dt>
<dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt> <dd>The document to run through the highlighter.</dd>
<dd>The mode to use (must be loaded as normal).</dd> <dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt>
<dt><code>output (function or DOM node)</code></dt> <dd>The mode to use (must be loaded as normal).</dd>
<dd>If this is a function, it will be called for each token with <dt><code>output (function or DOM node)</code></dt>
<dd>If this is a function, it will be called for each token with
two arguments, the token's text and the token's style class (may two arguments, the token's text and the token's style class (may
be <code>null</code> for unstyled tokens). If it is a DOM node, be <code>null</code> for unstyled tokens). If it is a DOM node,
the tokens will be converted to <code>span</code> elements as in the tokens will be converted to <code>span</code> elements as in
an editor, and inserted into the node an editor, and inserted into the node
(through <code>innerHTML</code>).</dd> (through <code>innerHTML</code>).
</dl> </dd>
</dl>
</article> </article>
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
<title>CodeMirror: Search/Replace Demo</title> <title>CodeMirror: Search/Replace Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/dialog/dialog.css"> <link href="../addon/dialog/dialog.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/search/matchesonscrollbar.css"> <link href="../addon/search/matchesonscrollbar.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
<script src="../addon/dialog/dialog.js"></script> <script src="../addon/dialog/dialog.js"></script>
...@@ -16,9 +16,16 @@ ...@@ -16,9 +16,16 @@
<script src="../addon/search/matchesonscrollbar.js"></script> <script src="../addon/search/matchesonscrollbar.js"></script>
<script src="../addon/search/jump-to-line.js"></script> <script src="../addon/search/jump-to-line.js"></script>
<style> <style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror {
dt {font-family: monospace; color: #666;} border-top: 1px solid black;
</style> border-bottom: 1px solid black;
}
dt {
font-family: monospace;
color: #666;
}
</style>
<div id=nav> <div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a> <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
...@@ -33,8 +40,8 @@ ...@@ -33,8 +40,8 @@
</div> </div>
<article> <article>
<h2>Search/Replace Demo</h2> <h2>Search/Replace Demo</h2>
<form><textarea id="code" name="code"> <form><textarea id="code" name="code">
<dl> <dl>
<dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt> <dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt>
<dd>Whether, when indenting, the first N*<code>tabSize</code> <dd>Whether, when indenting, the first N*<code>tabSize</code>
...@@ -69,31 +76,39 @@ ...@@ -69,31 +76,39 @@
</dl> </dl>
</textarea></form> </textarea></form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/html", mode: "text/html",
lineNumbers: true, lineNumbers: true,
extraKeys: {"Alt-F": "findPersistent"} extraKeys: {"Alt-F": "findPersistent"}
}); });
</script> </script>
<p>Demonstration of primitive search/replace functionality. The <p>Demonstration of primitive search/replace functionality. The
keybindings (which can be configured with custom keymaps) are:</p> keybindings (which can be configured with custom keymaps) are:</p>
<dl> <dl>
<dt>Ctrl-F / Cmd-F</dt><dd>Start searching</dd> <dt>Ctrl-F / Cmd-F</dt>
<dt>Ctrl-G / Cmd-G</dt><dd>Find next</dd> <dd>Start searching</dd>
<dt>Shift-Ctrl-G / Shift-Cmd-G</dt><dd>Find previous</dd> <dt>Ctrl-G / Cmd-G</dt>
<dt>Shift-Ctrl-F / Cmd-Option-F</dt><dd>Replace</dd> <dd>Find next</dd>
<dt>Shift-Ctrl-R / Shift-Cmd-Option-F</dt><dd>Replace all</dd> <dt>Shift-Ctrl-G / Shift-Cmd-G</dt>
<dt>Alt-F</dt><dd>Persistent search (dialog doesn't autoclose, <dd>Find previous</dd>
enter to find next, Shift-Enter to find previous)</dd> <dt>Shift-Ctrl-F / Cmd-Option-F</dt>
<dt>Alt-G</dt><dd>Jump to line</dd> <dd>Replace</dd>
</dl> <dt>Shift-Ctrl-R / Shift-Cmd-Option-F</dt>
<p>Searching is enabled by <dd>Replace all</dd>
<dt>Alt-F</dt>
<dd>Persistent search (dialog doesn't autoclose,
enter to find next, Shift-Enter to find previous)
</dd>
<dt>Alt-G</dt>
<dd>Jump to line</dd>
</dl>
<p>Searching is enabled by
including <a href="../addon/search/search.js">addon/search/search.js</a> including <a href="../addon/search/search.js">addon/search/search.js</a>
and <a href="../addon/search/searchcursor.js">addon/search/searchcursor.js</a>. and <a href="../addon/search/searchcursor.js">addon/search/searchcursor.js</a>.
Jump to line - including <a href="../addon/search/jump-to-line.js">addon/search/jump-to-line.js</a>.</p> Jump to line - including <a href="../addon/search/jump-to-line.js">addon/search/jump-to-line.js</a>.</p>
<p>For good-looking input dialogs, you also want to include <p>For good-looking input dialogs, you also want to include
<a href="../addon/dialog/dialog.js">addon/dialog/dialog.js</a> <a href="../addon/dialog/dialog.js">addon/dialog/dialog.js</a>
and <a href="../addon/dialog/dialog.css">addon/dialog/dialog.css</a>.</p> and <a href="../addon/dialog/dialog.css">addon/dialog/dialog.css</a>.</p>
</article> </article>
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<title>CodeMirror: Simple Scrollbar Demo</title> <title>CodeMirror: Simple Scrollbar Demo</title>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css"> <link href="../doc/docs.css" rel=stylesheet>
<link rel="stylesheet" href="../lib/codemirror.css"> <link href="../lib/codemirror.css" rel="stylesheet">
<link rel="stylesheet" href="../addon/scroll/simplescrollbars.css"> <link href="../addon/scroll/simplescrollbars.css" rel="stylesheet">
<script src="../lib/codemirror.js"></script> <script src="../lib/codemirror.js"></script>
<script src="../mode/markdown/markdown.js"></script> <script src="../mode/markdown/markdown.js"></script>
<script src="../mode/xml/xml.js"></script> <script src="../mode/xml/xml.js"></script>
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
</div> </div>
<article> <article>
<h2>Simple Scrollbar Demo</h2> <h2>Simple Scrollbar Demo</h2>
<form><textarea id="code" name="code"># Custom Scrollbars <form><textarea id="code" name="code"># Custom Scrollbars
This is a piece of text that creates scrollbars This is a piece of text that creates scrollbars
...@@ -67,11 +67,14 @@ maxime sem dapibus et eget, mi enim dignissim nec pretium, augue vehicula, volut ...@@ -67,11 +67,14 @@ maxime sem dapibus et eget, mi enim dignissim nec pretium, augue vehicula, volut
lobortis viverra, cum in sed, vivamus tellus. Libero at malesuada est vivamus leo tortor. lobortis viverra, cum in sed, vivamus tellus. Libero at malesuada est vivamus leo tortor.
</textarea></form> </textarea></form>
<p>The <a href="../doc/manual.html#addon_simplescrollbars"><code>simplescrollbars</code></a> addon defines two <p>The <a href="../doc/manual.html#addon_simplescrollbars"><code>simplescrollbars</code></a> addon defines two
styles of non-native scrollbars: <a href="javascript:editor.setOption('scrollbarStyle', 'simple')"><code>"simple"</code></a> and <a href="javascript:editor.setOption('scrollbarStyle', 'overlay')"><code>"overlay"</code></a> (click to try), which can be passed to styles of non-native scrollbars: <a
the <a href="../doc/manual.html#option_scrollbarStyle"><code>scrollbarStyle</code></a> option. These implement href="javascript:editor.setOption('scrollbarStyle', 'simple')"><code>"simple"</code></a> and <a
the scrollbar using DOM elements, allowing more control over href="javascript:editor.setOption('scrollbarStyle', 'overlay')"><code>"overlay"</code></a> (click to try), which
its <a href="../addon/scroll/simplescrollbars.css">appearance</a>.</p> can be passed to
the <a href="../doc/manual.html#option_scrollbarStyle"><code>scrollbarStyle</code></a> option. These implement
the scrollbar using DOM elements, allowing more control over
its <a href="../addon/scroll/simplescrollbars.css">appearance</a>.</p>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
document.createElement("section"); document.createElement("section");
document.createElement("article"); document.createElement("article");
(function() { (function () {
if (!window.addEventListener) return; if (!window.addEventListener) return;
var pending = false, prevVal = null; var pending = false, prevVal = null;
...@@ -44,12 +44,15 @@ document.createElement("article"); ...@@ -44,12 +44,15 @@ document.createElement("article");
window.addEventListener("scroll", updateSoon); window.addEventListener("scroll", updateSoon);
window.addEventListener("load", updateSoon); window.addEventListener("load", updateSoon);
window.addEventListener("hashchange", function() { window.addEventListener("hashchange", function () {
setTimeout(function() { setTimeout(function () {
var hash = document.location.hash, found = null, m; var hash = document.location.hash, found = null, m;
var marks = document.getElementById("nav").getElementsByTagName("a"); var marks = document.getElementById("nav").getElementsByTagName("a");
for (var i = 0; i < marks.length; i++) for (var i = 0; i < marks.length; i++)
if ((m = marks[i].href.match(/(#.*)/)) && m[1] == hash) { found = i; break; } if ((m = marks[i].href.match(/(#.*)/)) && m[1] == hash) {
found = i;
break;
}
if (found != null) for (var i = 0; i < marks.length; i++) if (found != null) for (var i = 0; i < marks.length; i++)
marks[i].className = i == found ? "active" : ""; marks[i].className = i == found ? "active" : "";
}, 300); }, 300);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment