Permalink
Browse files

first commit

  • Loading branch information...
guillaumebort committed Jan 20, 2010
0 parents commit 14090f9ac80572ed99f38dee22f853e27613c339
Showing with 1,710 additions and 0 deletions.
  1. +67 −0 clipboard.js
  2. +28 −0 core.js
  3. +159 −0 cursor.js
  4. +610 −0 editor.js
  5. +60 −0 history.js
  6. +117 −0 model.js
  7. +383 −0 parser.js
  8. +162 −0 preview.js
  9. +124 −0 theme.js
@@ -0,0 +1,67 @@
+/** Pretty dumb clipboard implementation **/
+Textile.Clipboard = Textile.Utils.makeClass({
+
+ constructor: function(editor) {
+ this.editor = editor;
+ this.clipboard = document.createElement('textarea');
+ document.body.appendChild(this.clipboard);
+ this.clipboard.style.position = 'absolute';
+ this.clipboard.style.width = '100px';
+ this.clipboard.style.height = '100px';
+ this.clipboard.style.top = this.editor.getPosition().top + 'px';
+ this.clipboard.style.left = '-999em';
+ this.clipboard.autocomplete = 'off';
+ this.clipboard.tabIndex = '-1';
+ },
+
+ cut: function() {
+ var data = this.selected();
+ if(data) {
+ this.copyToClipboard(data);
+ this.editor.model.replace(this.editor.selection.from, this.editor.selection.to, '');
+ this.editor.cursor.toPosition(this.editor.selection.from);
+ this.editor.selection = null;
+ this.editor.cursor.focus();
+ this.editor.paint();
+ }
+ },
+
+ copy: function() {
+ var data = this.selected();
+ if(data) {
+ this.copyToClipboard(data);
+ }
+ },
+
+ paste: function() {
+ this.clipboard.select();
+ setTimeout(Textile.Utils.bind(function() {
+ var data = this.clipboard.value;
+ if(data) {
+ if(this.editor.selection) {
+ this.editor.model.replace(this.editor.selection.from, this.editor.selection.to, data);
+ this.editor.cursor.toPosition(this.editor.selection.from + data.length);
+ this.editor.selection = null;
+ } else {
+ this.editor.model.insert(this.editor.cursor.getPosition(), data);
+ this.editor.cursor.toPosition(this.editor.cursor.getPosition() + data.length);
+ }
+ this.editor.cursor.focus();
+ this.editor.paint();
+ }
+ }, this), 0);
+ },
+
+ copyToClipboard: function(data) {
+ this.clipboard.value = data;
+ this.clipboard.select();
+ },
+
+ selected: function() {
+ if(!this.editor.selection) {
+ return '';
+ }
+ return this.editor.model.content.substring(this.editor.selection.from, this.editor.selection.to);
+ }
+
+});
28 core.js
@@ -0,0 +1,28 @@
+var Textile = {};
+
+/** Some utils **/
+Textile.Utils = {
+
+ bind: function(func, o) {
+ return function() {
+ func.apply(o, arguments);
+ }
+ },
+
+ makeClass: function(methods) {
+ var fn = function(args) {
+ if(!args) {
+ args = {};
+ }
+ if(!(this instanceof arguments.callee)) {
+ return new arguments.callee(arguments);
+ }
+ if( typeof this.constructor == "function") {
+ this.constructor.apply(this, args.callee ? args : arguments);
+ }
+ };
+ fn.prototype = methods;
+ return fn;
+ }
+
+}
159 cursor.js
@@ -0,0 +1,159 @@
+/** Cursor **/
+Textile.Cursor = Textile.Utils.makeClass({
+
+ line: 1,
+ column: 0,
+ pref_column: 0,
+ show: false,
+ editor: null,
+
+ constructor: function(editor) {
+ this.editor = editor;
+ setInterval(Textile.Utils.bind(this.toggle, this), 500);
+ },
+
+ onChange: function(handler) {
+ this.onChangeHandler = handler;
+ },
+
+ _notify: function(speed) {
+ if(this.onChangeHandler) {
+ this.onChangeHandler(speed);
+ }
+ },
+
+ toggle: function() {
+ if(this.editor.hasFocus) {
+ this.show = !this.show;
+ this.editor.paint();
+ }
+ },
+
+ fromPointer: function(position) {
+ this.line = Math.round((position.y + (this.editor.lineHeight/2)) / this.editor.lineHeight) + this.editor.first_line - 1;
+ this.column = Math.round(position.x / this.editor.charWidth);
+ this.pref_column = this.column;
+ this.bound();
+ this.show = true;
+ this._notify();
+ },
+
+ isVisible: function() {
+ return this.isLineVisible(this.line);
+ },
+
+ isLineVisible: function(line) {
+ return line >= this.editor.first_line && line < this.editor.first_line + this.editor.lines;
+ },
+
+ focus: function() {
+ if(!this.isVisible()) {
+ if(this.line < this.editor.first_line) {
+ this.editor.first_line = this.line;
+ } else {
+ this.editor.first_line = this.line - this.editor.lines + 1;
+ }
+ }
+ this.editor.paint();
+ this._notify('now');
+ },
+
+ lineDown: function() {
+ if(this.editor.selection) {
+ this.toPosition(this.editor.selection.to);
+ this.editor.selection = null;
+ }
+ this.line++;
+ if(this.pref_column > this.column) {
+ this.column = this.pref_column;
+ }
+ this.bound();
+ },
+
+ lineUp: function() {
+ if(this.editor.selection) {
+ this.toPosition(this.editor.selection.from);
+ this.editor.selection = null;
+ }
+ this.line--;
+ if(this.pref_column > this.column) {
+ this.column = this.pref_column;
+ }
+ this.bound();
+ },
+
+ left: function() {
+ if(this.editor.selection) {
+ this.toPosition(this.editor.selection.from);
+ this.editor.selection = null;
+ } else {
+ this.toPosition(this.getPosition() - 1);
+ }
+ this.pref_column = this.column;
+ },
+
+ right: function(keyboardSelect) {
+ if(!keyboardSelect && this.editor.selection) {
+ this.toPosition(this.editor.selection.to);
+ this.editor.selection = null;
+ } else {
+ this.toPosition(this.getPosition() + 1);
+ }
+ this.pref_column = this.column;
+ },
+
+ bound: function() {
+ if(this.line < 1) {
+ this.line = 1;
+ }
+ if(this.editor.first_line < 1) {
+ this.editor.first_line = 1;
+ }
+ if(this.line > this.editor.model.lines.length) {
+ this.line = this.editor.model.lines.length;
+ }
+ if(this.editor.first_line > this.editor.model.lines.length - this.editor.lines + 1) {
+ this.editor.first_line = this.editor.model.lines.length - this.editor.lines + 1;
+ if(this.editor.first_line < 1) {
+ this.editor.first_line = 1;
+ }
+ }
+ if(this.column < 0) {
+ this.column = 0;
+ }
+ var content = this.editor.model.lines[this.line - 1].content;
+ if(this.column > content.length) {
+ this.column = content.length;
+ }
+ },
+
+ getPosition: function() {
+ return this.editor.model.lines[this.line - 1].offset + this.column;
+ },
+
+ toPosition: function(position) {
+ if(!position || position < 0) {
+ position = 0;
+ }
+ for(var i=0; i<this.editor.model.lines.length; i++) {
+ if(this.editor.model.lines[i].offset > position) {
+ this.line = i;
+ this.column = position - this.editor.model.lines[i-1].offset;
+ this.pref_column = this.column;
+ if(this.line < 1) {
+ return;
+ }
+ this.bound();
+ return;
+ }
+ }
+ this.line = this.editor.model.lines.length;
+ this.column = position - this.editor.model.lines[i-1].offset;
+ this.pref_column = this.column;
+ if(this.line < 1) {
+ return;
+ }
+ this.bound();
+ }
+
+});
Oops, something went wrong.

0 comments on commit 14090f9

Please sign in to comment.