1 //use case: edytor robi split, jesli split był na koncu (czyli druga czesc jest pusta)
 
   2 // chce tam dodac wezel tekstowy
 
   4 // flow: plugin_key_handler(enter, main-canvas-area) -> plugin_document_action('break-content')
 
   5 // --w srodku--> refactoring tego co teraz w keyboard:
 
   7 //1. jedna transformacja z warunkiem (Zarejestrowana przez plugin)
 
  11 var breakContentTransformation = {
 
  12     impl: function(args) {
 
  13         var node = this.context;
 
  18         newNodes = node.transform('core.split', {offset: args.offset});
 
  21             emptyNode = newNodes.first;
 
  22         else if(args.offset === node.getText().length); //@ nie ma atEnd :(
 
  23             emptyNode = newNodes.second;
 
  26             emptyText = emptyNode.transform('core.append', {text: ''});
 
  29         return _.extend(newNodes, {emptyText: emptyText});
 
  34 var breakContentAction = function(document, context) {
 
  35     var textNode = context.currentTextNode;
 
  39         result = textNode.transform('core.break-content', {offset: context.offset});
 
  41         if(result.emptyText) {
 
  42             goto = result.createdEmpty;
 
  46             gotoOptions = {caretTo: 'start'};   
 
  49         context.setCurrentElement(goto, gotoOptions);
 
  55         {key: 'ENTER', target: 'main-document-area', handler: function(editor) {
 
  56             editor.getAction('core.break-document-content').execute();
 
  61         {name: 'core.break-document-content', context: 'main-document-area', action: breakContentAction}
 
  64     // zapisywanie dokumentu:
 
  66     contextTransformations: [
 
  67         {name: 'core.break-content', textNode: true, t: breakContentTransformation},
 
  70         {name: 'list.remove-list', elementNode: 'list', t: null}
 
  71         // hipotetyczna akcja na itemie listy
 
  72         {name: 'list.extract', elementNode: 'item', requiresParent: 'list', requiresInParents: '?'}
 
  80 // 1. detach via totalny fallback
 
  81 var DetachNodeTransformation = function(args) {
 
  82     this.node = args.node;
 
  83     this.document = this.node.document;
 
  85 $.extend(DetachNodeTransformation.prototype, {
 
  87         this.oldRoot = this.node.document.root.clone();
 
  88         this.path = this.node.getPath();
 
  89         this.node.detach(); // @TS
 
  93         this.document.root.replaceWith(this.oldRoot); // this.getDocument?
 
  94         this.node = this.document.getNodeByPath(this.path);
 
  97 transformations['detach'] = DetachNodeTransformation;
 
  99 //2. detach via wskazanie changeroot
 
 101 var Detach2NodeTransformation = function(args) {
 
 102     this.nodePath = args.node.getPath();
 
 103     this.document = args.node.document;
 
 105 $.extend(Detach2NodeTransformation.prototype, {
 
 107         var node = this.document.getNodeByPath(this.nodePath),
 
 108             root = node.parent() ? node.parent() : this.document.root;
 
 110         this.rootPath = root.getPath();
 
 111         this.oldRoot = (root).clone();
 
 115         this.document.getNodeByPath(this.rootPath).replaceWith(this.oldRoot);
 
 118 //transformations['detach2'] = Detach2NodeTransformation;
 
 120 //2a. generyczna transformacja
 
 122 var createTransformation = function(desc) {
 
 124     var NodeTransformation = function(args) {
 
 125         this.nodePath = args.node.getPath();
 
 126         this.document = args.node.document;
 
 129     $.extend(NodeTransformation.prototype, {
 
 131             var node = this.document.getNodeByPath(this.nodePath),
 
 135                 root = desc.getRoot(node);
 
 137                 root = this.document.root;
 
 140             this.rootPath = root.getPath();
 
 141             this.oldRoot = (root).clone();
 
 142             desc.impl.call(node, this.args);
 
 145             this.document.getNodeByPath(this.rootPath).replaceWith(this.oldRoot);
 
 149     return NodeTransformation;
 
 154 var contextTransformations = {};
 
 155 contextTransformations['setText'] = createContextTransformation({
 
 156     impl: function(args) {
 
 157         this.setText(args.text);
 
 159     getChangeRoot: function() {
 
 164 contextTransformations['setAttr'] = createContextTransformation({
 
 165     impl: function(args) {
 
 166         this.setAttr(args.name, args.value);
 
 168     getChangeRoot: function() {
 
 173 contextTransformations['split'] = createContextTransformation({
 
 174     impl: function(args) {
 
 175         return this.split({offset: args.offset});
 
 177     // getChangeRoot: function() {
 
 178     //     return this.context.parent().parent();
 
 183 contextTransformations['before'] = createContextTransformation({
 
 184     getChangeRoot: function() {
 
 185         return this.context.parent();
 
 187     impl: function(args) {
 
 188         this.before(args.node)
 
 193 contextTransformations['before'] = createContextTransformation({
 
 194     impl: function(args) {
 
 195         this.before(args.node)
 
 198         this.context.detach();
 
 204 transformations['detach2'] = createTransformation({
 
 205     // impl: function() {
 
 206     //     //this.setAttr('class', 'cite'); //  
 
 208     impl: ElementNode.prototype.detach,
 
 209     getRoot: function(node) {
 
 210         return node.parent();
 
 215 transformations['setText-old'] = createTransformation({
 
 216     impl: function(args) {
 
 217         this.setText(args.text)
 
 219     getRoot: function(node) {
 
 225 transformations['setClass-old'] = createTransformation({
 
 226     impl: function(args) {
 
 227         this.setClass(args.klass);
 
 229     getRoot: function(node) {
 
 234 //3. detach z pełnym własnym redo
 
 236 var Detach3NodeTransformation = function(args) {
 
 237     this.node = args.node;
 
 238     this.document = this.node.document;
 
 240 $.extend(Detach3NodeTransformation.prototype, {
 
 242         //this.index = this.node.getIndex();
 
 243         //this.parent = this.node.parent();
 
 245         this.path = this.node.getPath();
 
 246         if(this.node.isSurroundedByTextElements()) {
 
 247             this.prevText = this.node.prev().getText();
 
 248             this.nextText = this.node.next().getText();
 
 251             this.prevText = this.nextText = null;
 
 258         var parent = this.document.getNodeByPath(this.path.slice(0,-1)),
 
 259             idx = _.last(this.path);
 
 260         var inserted = parent.insertAtIndex(this.node, idx);
 
 262             if(inserted.next()) {
 
 263                 inserted.before({text: this.prevText});
 
 264                 inserted.next().setText(this.nextText);
 
 266                 inserted.prev().setText(this.prevText);
 
 267                 inserted.after({text: this.nextText});
 
 272 transformations['detach3'] = Detach3NodeTransformation;
 
 275 var registerTransformationsFromObject = function(object) {
 
 276     _.pairs(object).filter(function(pair) {
 
 277         var property = pair[1];
 
 278         return typeof property === 'function' && property._isTransformation;
 
 280     .forEach(function(pair) {
 
 283         object.registerTransformation(name, createContextTransformation(method));
 
 286 registerTransformationsFromObject(ElementNode.prototype);
 
 287 registerTransformationsFromObject(TextNode.prototype);
 
 288 registerTransformationsFromObject(Document.prototype);