aboutsummaryrefslogtreecommitdiff
path: root/js/document/html-document.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/document/html-document.js')
-rwxr-xr-xjs/document/html-document.js248
1 files changed, 210 insertions, 38 deletions
diff --git a/js/document/html-document.js b/js/document/html-document.js
index 5d507476..23b55e92 100755
--- a/js/document/html-document.js
+++ b/js/document/html-document.js
@@ -59,6 +59,27 @@ exports.HTMLDocument = Montage.create(TextDocument, {
59 _gridVerticalSpacing: {value:0}, 59 _gridVerticalSpacing: {value:0},
60 //end - drawUtils state 60 //end - drawUtils state
61 61
62 _undoStack: { value: [] },
63 undoStack: {
64 get: function() {
65 return this._undoStack;
66 },
67 set:function(value){
68 this._undoStack = value;
69 }
70 },
71
72 _redoStack: { value: [], enumerable: false },
73
74 redoStack: {
75 get: function() {
76 return this._redoStack;
77 },
78 set:function(value){
79 this._redoStack = value;
80 }
81 },
82
62 83
63 // GETTERS / SETTERS 84 // GETTERS / SETTERS
64 85
@@ -387,10 +408,69 @@ exports.HTMLDocument = Montage.create(TextDocument, {
387 // 408 //
388 if(!this.documentRoot.Ninja) this.documentRoot.Ninja = {}; 409 if(!this.documentRoot.Ninja) this.documentRoot.Ninja = {};
389 //Inserting user's document into template 410 //Inserting user's document into template
390 this._templateDocument.head.innerHTML = this._userDocument.content.head; 411
391 this._templateDocument.body.innerHTML = this._userDocument.content.body; 412
392 //TODO: Use querySelectorAll 413
393 var scripttags = this._templateDocument.html.getElementsByTagName('script'), webgldata; 414
415
416
417
418
419
420 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
421 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
422 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
423
424 //TODO: Clean up and make public method to prepend properties with Ninja URL
425 this._templateDocument.head.innerHTML = (this._userDocument.content.head.replace(/\b(href|src)\s*=\s*"([^"]*)"/g, ninjaUrlRedirect.bind(this))).replace(/url\(([^"]*)(.+?)\1\)/g, ninjaUrlRedirect.bind(this));
426 this._templateDocument.body.innerHTML = (this._userDocument.content.body.replace(/\b(href|src)\s*=\s*"([^"]*)"/g, ninjaUrlRedirect.bind(this))).replace(/url\(([^"]*)(.+?)\1\)/g, ninjaUrlRedirect.bind(this));
427 //
428 //var docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/'));
429 //
430 function ninjaUrlRedirect (prop) {
431 //Checking for property value to not contain a full direct URL
432 if (!prop.match(/(\b(?:(?:https?|ftp|file|[A-Za-z]+):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$]))/gi)) {
433 //Checking for attributes and type of source
434 if (prop.indexOf('href') !== -1 || prop.indexOf('src') !== -1) { //From HTML attribute
435 //
436 prop = prop.replace(/"([^"]*)"/gi, ninjaUrlPrepend.bind(this));
437 } else if (prop.indexOf('url') !== -1) { //From CSS property
438 //TODO: Add functionality
439 var docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/'));
440 prop = prop.replace(/[^()\\""\\'']+/g, cssUrlToNinjaUrl);
441 function cssUrlToNinjaUrl (s) {
442 if (s !== 'url') {
443 s = docRootUrl + s;
444 }
445 return s;
446 }
447 }
448 }
449 return prop;
450 }
451 //
452 function ninjaUrlPrepend (url) {
453 var docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/'));
454 if (url.indexOf('data:image') !== -1) {
455 return url;
456 } else {
457 return '"'+docRootUrl+url.replace(/\"/gi, '')+'"';
458 }
459 }
460 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
461 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
462 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
463
464
465
466
467
468
469
470
471
472
473 var scripttags = this._templateDocument.html.getElementsByTagName('script'), webgldata; //TODO: Use querySelectorAll
394 // 474 //
395 for (var w in scripttags) { 475 for (var w in scripttags) {
396 if (scripttags[w].getAttribute) { 476 if (scripttags[w].getAttribute) {
@@ -464,16 +544,18 @@ exports.HTMLDocument = Montage.create(TextDocument, {
464 //If rules are null, assuming cross-origin issue 544 //If rules are null, assuming cross-origin issue
465 if(this._document.styleSheets[i].rules === null) { 545 if(this._document.styleSheets[i].rules === null) {
466 //TODO: Revisit URLs and URI creation logic, very hack right now 546 //TODO: Revisit URLs and URI creation logic, very hack right now
467 var fileUri, cssUrl, cssData, tag, query; 547 var fileUri, cssUrl, cssData, query, prefixUrl, fileCouldDirUrl, docRootUrl;
468 if (this._document.styleSheets[i].href.indexOf('js/document/templates/montage-html') !== -1) { 548 //
469 //Getting the url of the CSS file 549 docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/'));
470 cssUrl = this._document.styleSheets[i].href.split('js/document/templates/montage-html')[1]; 550 //TODO: Parse out relative URLs and map them to absolute
471 //Creating the URI of the file (this is wrong should not be splitting cssUrl) 551 if (this._document.styleSheets[i].href.indexOf(this.application.ninja.coreIoApi.rootUrl) !== -1) {
472 fileUri = this.application.ninja.coreIoApi.cloudData.root+this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]+cssUrl.split('/')[1]; 552 //
473 //Loading the data from the file 553 cssUrl = this._document.styleSheets[i].href.split(this.application.ninja.coreIoApi.rootUrl)[1];
554 fileUri = this.application.ninja.coreIoApi.cloudData.root+cssUrl;
555 //TODO: Add error handling for reading file
474 cssData = this.application.ninja.coreIoApi.readFile({uri: fileUri}); 556 cssData = this.application.ninja.coreIoApi.readFile({uri: fileUri});
475 //Creating tag with file content 557 //
476 tag = this.iframe.contentWindow.document.createElement('style'); 558 var tag = this.iframe.contentWindow.document.createElement('style');
477 tag.setAttribute('type', 'text/css'); 559 tag.setAttribute('type', 'text/css');
478 tag.setAttribute('data-ninja-uri', fileUri); 560 tag.setAttribute('data-ninja-uri', fileUri);
479 tag.setAttribute('data-ninja-file-url', cssUrl); 561 tag.setAttribute('data-ninja-file-url', cssUrl);
@@ -481,11 +563,32 @@ exports.HTMLDocument = Montage.create(TextDocument, {
481 tag.setAttribute('data-ninja-file-name', cssUrl.split('/')[cssUrl.split('/').length-1]); 563 tag.setAttribute('data-ninja-file-name', cssUrl.split('/')[cssUrl.split('/').length-1]);
482 //Copying attributes to maintain same properties as the <link> 564 //Copying attributes to maintain same properties as the <link>
483 for (var n in this._document.styleSheets[i].ownerNode.attributes) { 565 for (var n in this._document.styleSheets[i].ownerNode.attributes) {
484 if (this._document.styleSheets[i].ownerNode.attributes[n].value && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled') { 566 if (this._document.styleSheets[i].ownerNode.attributes[n].value && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled' && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled') {
485 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value); 567 if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) {
568 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]);
569 } else {
570 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value);
571 }
572 }
573 }
574 //
575 fileCouldDirUrl = this._document.styleSheets[i].href.split(this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1])[0];
576
577 tag.innerHTML = cssData.content.replace(/url\(()(.+?)\1\)/g, detectUrl);
578
579 function detectUrl (prop) {
580 return prop.replace(/[^()\\""\\'']+/g, prefixUrl);;
581 }
582
583 function prefixUrl (url) {
584 if (url !== 'url') {
585 if (!url.match(/(\b(?:(?:https?|ftp|file|[A-Za-z]+):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$]))/gi)) {
586 url = fileCouldDirUrl+url;
587 }
486 } 588 }
589 return url;
487 } 590 }
488 tag.innerHTML = cssData.content; 591
489 //Looping through DOM to insert style tag at location of link element 592 //Looping through DOM to insert style tag at location of link element
490 query = this._templateDocument.html.querySelectorAll(['link']); 593 query = this._templateDocument.html.querySelectorAll(['link']);
491 for (var j in query) { 594 for (var j in query) {
@@ -498,13 +601,23 @@ exports.HTMLDocument = Montage.create(TextDocument, {
498 } 601 }
499 } else { 602 } else {
500 console.log('ERROR: Cross-Domain-Stylesheet detected, unable to load in Ninja'); 603 console.log('ERROR: Cross-Domain-Stylesheet detected, unable to load in Ninja');
501 /* 604 //None local stylesheet, probably on a CDN (locked)
502//None local stylesheet, probably on a CDN (locked) 605 var tag = this.iframe.contentWindow.document.createElement('style');
503 tag = this.iframe.contentWindow.document.createElement('style');
504 tag.setAttribute('type', 'text/css'); 606 tag.setAttribute('type', 'text/css');
505 tag.setAttribute('data-ninja-external-url', this._document.styleSheets[i].href); 607 tag.setAttribute('data-ninja-external-url', this._document.styleSheets[i].href);
506 tag.setAttribute('data-ninja-file-read-only', "true"); 608 tag.setAttribute('data-ninja-file-read-only', "true");
507 tag.setAttribute('data-ninja-file-name', this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1]); 609 tag.setAttribute('data-ninja-file-name', this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1]);
610 //Copying attributes to maintain same properties as the <link>
611 for (var n in this._document.styleSheets[i].ownerNode.attributes) {
612 if (this._document.styleSheets[i].ownerNode.attributes[n].value && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled' && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled') {
613 if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) {
614 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]);
615 } else {
616 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value);
617 }