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);