diff options
Diffstat (limited to 'js/document/html-document.js')
-rwxr-xr-x | js/document/html-document.js | 242 |
1 files changed, 206 insertions, 36 deletions
diff --git a/js/document/html-document.js b/js/document/html-document.js index b2113623..b9944d66 100755 --- a/js/document/html-document.js +++ b/js/document/html-document.js | |||
@@ -60,6 +60,27 @@ exports.HTMLDocument = Montage.create(TextDocument, { | |||
60 | _gridVerticalSpacing: {value:0}, | 60 | _gridVerticalSpacing: {value:0}, |
61 | //end - drawUtils state | 61 | //end - drawUtils state |
62 | 62 | ||
63 | _undoStack: { value: [] }, | ||
64 | undoStack: { | ||
65 | get: function() { | ||
66 | return this._undoStack; | ||
67 | }, | ||
68 | set:function(value){ | ||
69 | this._undoStack = value; | ||
70 | } | ||
71 | }, | ||
72 | |||
73 | _redoStack: { value: [], enumerable: false }, | ||
74 | |||
75 | redoStack: { | ||
76 | get: function() { | ||
77 | return this._redoStack; | ||
78 | }, | ||
79 | set:function(value){ | ||
80 | this._redoStack = value; | ||
81 | } | ||
82 | }, | ||
83 | |||
63 | 84 | ||
64 | // GETTERS / SETTERS | 85 | // GETTERS / SETTERS |
65 | 86 | ||
@@ -507,10 +528,69 @@ exports.HTMLDocument = Montage.create(TextDocument, { | |||
507 | // | 528 | // |
508 | if(!this.documentRoot.Ninja) this.documentRoot.Ninja = {}; | 529 | if(!this.documentRoot.Ninja) this.documentRoot.Ninja = {}; |
509 | //Inserting user's document into template | 530 | //Inserting user's document into template |
510 | this._templateDocument.head.innerHTML = this._userDocument.content.head; | 531 | |
511 | this._templateDocument.body.innerHTML = this._userDocument.content.body; | 532 | |
512 | //TODO: Use querySelectorAll | 533 | |
513 | var scripttags = this._templateDocument.html.getElementsByTagName('script'), webgldata; | 534 | |
535 | |||
536 | |||
537 | |||
538 | |||
539 | |||
540 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
541 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
542 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
543 | |||
544 | //TODO: Clean up and make public method to prepend properties with Ninja URL | ||
545 | 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)); | ||
546 | 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)); | ||
547 | // | ||
548 | //var docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/')); | ||
549 | // | ||
550 | function ninjaUrlRedirect (prop) { | ||
551 | //Checking for property value to not contain a full direct URL | ||
552 | 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)) { | ||
553 | //Checking for attributes and type of source | ||
554 | if (prop.indexOf('href') !== -1 || prop.indexOf('src') !== -1) { //From HTML attribute | ||
555 | // | ||
556 | prop = prop.replace(/"([^"]*)"/gi, ninjaUrlPrepend.bind(this)); | ||
557 | } else if (prop.indexOf('url') !== -1) { //From CSS property | ||
558 | //TODO: Add functionality | ||
559 | var docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/')); | ||
560 | prop = prop.replace(/[^()\\""\\'']+/g, cssUrlToNinjaUrl); | ||
561 | function cssUrlToNinjaUrl (s) { | ||
562 | if (s !== 'url') { | ||
563 | s = docRootUrl + s; | ||
564 | } | ||
565 | return s; | ||
566 | } | ||
567 | } | ||
568 | } | ||
569 | return prop; | ||
570 | } | ||
571 | // | ||
572 | function ninjaUrlPrepend (url) { | ||
573 | var docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/')); | ||
574 | if (url.indexOf('data:image') !== -1) { | ||
575 | return url; | ||
576 | } else { | ||
577 | return '"'+docRootUrl+url.replace(/\"/gi, '')+'"'; | ||
578 | } | ||
579 | } | ||
580 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
581 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
582 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
583 | |||
584 | |||
585 | |||
586 | |||
587 | |||
588 | |||
589 | |||
590 | |||
591 | |||
592 | |||
593 | var scripttags = this._templateDocument.html.getElementsByTagName('script'), webgldata; //TODO: Use querySelectorAll | ||
514 | // | 594 | // |
515 | for (var w in scripttags) { | 595 | for (var w in scripttags) { |
516 | if (scripttags[w].getAttribute) { | 596 | if (scripttags[w].getAttribute) { |
@@ -584,16 +664,18 @@ exports.HTMLDocument = Montage.create(TextDocument, { | |||
584 | //If rules are null, assuming cross-origin issue | 664 | //If rules are null, assuming cross-origin issue |
585 | if(this._document.styleSheets[i].rules === null) { | 665 | if(this._document.styleSheets[i].rules === null) { |
586 | //TODO: Revisit URLs and URI creation logic, very hack right now | 666 | //TODO: Revisit URLs and URI creation logic, very hack right now |
587 | var fileUri, cssUrl, cssData, tag, query; | 667 | var fileUri, cssUrl, cssData, query, prefixUrl, fileCouldDirUrl, docRootUrl; |
588 | if (this._document.styleSheets[i].href.indexOf('js/document/templates/montage-html') !== -1) { | 668 | // |
589 | //Getting the url of the CSS file | 669 | docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/')); |
590 | cssUrl = this._document.styleSheets[i].href.split('js/document/templates/montage-html')[1]; | 670 | //TODO: Parse out relative URLs and map them to absolute |
591 | //Creating the URI of the file (this is wrong should not be splitting cssUrl) | 671 | if (this._document.styleSheets[i].href.indexOf(this.application.ninja.coreIoApi.rootUrl) !== -1) { |
592 | fileUri = this.application.ninja.coreIoApi.cloudData.root+this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]+cssUrl.split('/')[1]; | 672 | // |
593 | //Loading the data from the file | 673 | cssUrl = this._document.styleSheets[i].href.split(this.application.ninja.coreIoApi.rootUrl)[1]; |
674 | fileUri = this.application.ninja.coreIoApi.cloudData.root+cssUrl; | ||
675 | //TODO: Add error handling for reading file | ||
594 | cssData = this.application.ninja.coreIoApi.readFile({uri: fileUri}); | 676 | cssData = this.application.ninja.coreIoApi.readFile({uri: fileUri}); |
595 | //Creating tag with file content | 677 | // |
596 | tag = this.iframe.contentWindow.document.createElement('style'); | 678 | var tag = this.iframe.contentWindow.document.createElement('style'); |
597 | tag.setAttribute('type', 'text/css'); | 679 | tag.setAttribute('type', 'text/css'); |
598 | tag.setAttribute('data-ninja-uri', fileUri); | 680 | tag.setAttribute('data-ninja-uri', fileUri); |
599 | tag.setAttribute('data-ninja-file-url', cssUrl); | 681 | tag.setAttribute('data-ninja-file-url', cssUrl); |
@@ -601,11 +683,32 @@ exports.HTMLDocument = Montage.create(TextDocument, { | |||
601 | tag.setAttribute('data-ninja-file-name', cssUrl.split('/')[cssUrl.split('/').length-1]); | 683 | tag.setAttribute('data-ninja-file-name', cssUrl.split('/')[cssUrl.split('/').length-1]); |
602 | //Copying attributes to maintain same properties as the <link> | 684 | //Copying attributes to maintain same properties as the <link> |
603 | for (var n in this._document.styleSheets[i].ownerNode.attributes) { | 685 | for (var n in this._document.styleSheets[i].ownerNode.attributes) { |
604 | if (this._document.styleSheets[i].ownerNode.attributes[n].value && this._document.styleSheets[i].ownerNode.attributes[n].name !== 'disabled') { | 686 | 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') { |
605 | tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value); | 687 | if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) { |
688 | tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]); | ||
689 | } else { | ||
690 | tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value); | ||
691 | } | ||
692 | } | ||
693 | } | ||
694 | // | ||
695 | fileCouldDirUrl = this._document.styleSheets[i].href.split(this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1])[0]; | ||
696 | |||
697 | tag.innerHTML = cssData.content.replace(/url\(()(.+?)\1\)/g, detectUrl); | ||
698 | |||
699 | function detectUrl (prop) { | ||
700 | return prop.replace(/[^()\\""\\'']+/g, prefixUrl);; | ||
701 | } | ||
702 | |||
703 | function prefixUrl (url) { | ||
704 | if (url !== 'url') { | ||
705 | 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)) { | ||
706 | url = fileCouldDirUrl+url; | ||
707 | } | ||
606 | } | 708 | } |
709 | return url; | ||
607 | } | 710 | } |
608 | tag.innerHTML = cssData.content; | 711 | |
609 | //Looping through DOM to insert style tag at location of link element | 712 | //Looping through DOM to insert style tag at location of link element |
610 | query = this._templateDocument.html.querySelectorAll(['link']); | 713 | query = this._templateDocument.html.querySelectorAll(['link']); |
611 | for (var j in query) { | 714 | for (var j in query) { |
@@ -618,13 +721,23 @@ exports.HTMLDocument = Montage.create(TextDocument, { | |||
618 | } | 721 | } |
619 | } else { | 722 | } else { |
620 | console.log('ERROR: Cross-Domain-Stylesheet detected, unable to load in Ninja'); | 723 | console.log('ERROR: Cross-Domain-Stylesheet detected, unable to load in Ninja'); |
621 | /* | 724 | //None local stylesheet, probably on a CDN (locked) |
622 | //None local stylesheet, probably on a CDN (locked) | 725 | var tag = this.iframe.contentWindow.document.createElement('style'); |
623 | tag = this.iframe.contentWindow.document.createElement('style'); | ||
624 | tag.setAttribute('type', 'text/css'); | 726 | tag.setAttribute('type', 'text/css'); |
625 | tag.setAttribute('data-ninja-external-url', this._document.styleSheets[i].href); | 727 | tag.setAttribute('data-ninja-external-url', this._document.styleSheets[i].href); |
626 | tag.setAttribute('data-ninja-file-read-only', "true"); | 728 | tag.setAttribute('data-ninja-file-read-only', "true"); |
627 | tag.setAttribute('data-ninja-file-name', this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1]); | 729 | tag.setAttribute('data-ninja-file-name', this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1]); |
730 | //Copying attributes to maintain same properties as the <link> | ||
731 | for (var n in this._document.styleSheets[i].ownerNode.attributes) { | ||
732 | 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') { | ||
733 | if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) { | ||
734 | tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]); | ||
735 | } else { | ||
736 |