aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xjs/document/document-html.js229
1 files changed, 13 insertions, 216 deletions
diff --git a/js/document/document-html.js b/js/document/document-html.js
index ec59c3e2..deca9f83 100755
--- a/js/document/document-html.js
+++ b/js/document/document-html.js
@@ -30,6 +30,11 @@ exports.HtmlDocument = Montage.create(Component, {
30 }, 30 },
31 //////////////////////////////////////////////////////////////////// 31 ////////////////////////////////////////////////////////////////////
32 // 32 //
33 _observer: {
34 value: null
35 },
36 ////////////////////////////////////////////////////////////////////
37 //
33 _document: { 38 _document: {
34 value: null //TODO: Figure out if this will be needed, probably not 39 value: null //TODO: Figure out if this will be needed, probably not
35 }, 40 },
@@ -80,7 +85,7 @@ exports.HtmlDocument = Montage.create(Component, {
80 this.model.views.design.show(); 85 this.model.views.design.show();
81 this.model.views.design.iframe.style.opacity = 0; 86 this.model.views.design.iframe.style.opacity = 0;
82 this.model.views.design.content = this.model.file.content; 87 this.model.views.design.content = this.model.file.content;
83 // 88 //TODO: Clean up
84 this.model.views.design.render(function () { 89 this.model.views.design.render(function () {
85 //TODO: Identify and remove usage of '_document' 90 //TODO: Identify and remove usage of '_document'
86 this._document = this.model.views.design.document; 91 this._document = this.model.views.design.document;
@@ -90,8 +95,9 @@ exports.HtmlDocument = Montage.create(Component, {
90 this._liveNodeList = this.documentRoot.getElementsByTagName('*'); 95 this._liveNodeList = this.documentRoot.getElementsByTagName('*');
91 //Initiliazing document model 96 //Initiliazing document model
92 document.application.njUtils.makeElementModel(this.documentRoot, "Body", "body"); 97 document.application.njUtils.makeElementModel(this.documentRoot, "Body", "body");
93 //Adding event to know when template is ready 98 //Adding observer to know when template is ready
94 this.model.views.design.document.head.addEventListener('DOMSubtreeModified', this.handleTemplateReady.bind(this), false); 99 this._observer = new WebKitMutationObserver(this.handleTemplateReady.bind(this));
100 this._observer.observe(this.model.views.design.document.head, {childList: true});
95 }.bind(this)); 101 }.bind(this));
96 } else { 102 } else {
97 //TODO: Identify default view (probably code) 103 //TODO: Identify default view (probably code)
@@ -102,226 +108,17 @@ exports.HtmlDocument = Montage.create(Component, {
102 // 108 //
103 handleTemplateReady: { 109 handleTemplateReady: {
104 value: function (e) { 110 value: function (e) {
105 //Removing event listener, a must for this type of event 111 //Removing observer, only needed on initial load
106 this.model.views.design.document.head.removeEventListener('DOMSubtreeModified', this.handleTemplateReady.bind(this), false); 112 this._observer.disconnect();
113 this._observer = null;
107 //Making callback after view is loaded 114 //Making callback after view is loaded
108 this.loaded.callback.call(this.loaded.context, this); 115 this.loaded.callback.call(this.loaded.context, this);
109 //Setting opacity to be viewable after load 116 //Setting opacity to be viewable after load
110 this.model.views.design.iframe.style.opacity = 1; 117 this.model.views.design.iframe.style.opacity = 1;
111 } 118 }
112 }, 119 }
113 //////////////////////////////////////////////////////////////////// 120 ////////////////////////////////////////////////////////////////////
114 //////////////////////////////////////////////////////////////////// 121 ////////////////////////////////////////////////////////////////////
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 handleWebTemplateLoad: {
151 value: function(event) {
152 //TODO: Remove, also for prototyping
153 this.application.ninja.documentController._hackRootFlag = true;
154
155 this._window = this.iframe.contentWindow;
156 this._document = this.iframe.contentWindow.document;
157 this.documentRoot = this.iframe.contentWindow.document.body;
158
159 for (var k in this._document.styleSheets) {
160 if (this._document.styleSheets[k].ownerNode && this._document.styleSheets[k].ownerNode.setAttribute) {
161 this._document.styleSheets[k].ownerNode.setAttribute('data-ninja-template', 'true');
162 }
163 }
164
165 // Live node list of the current loaded document
166 this._liveNodeList = this.documentRoot.getElementsByTagName('*');
167
168
169 setTimeout(function () {
170
171 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
172 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
173 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
174 if(this._document.styleSheets.length) {
175 //Checking all styleSheets in document
176 for (var i in this._document.styleSheets) {
177 //If rules are null, assuming cross-origin issue
178 if(this._document.styleSheets[i].rules === null) {
179 //TODO: Revisit URLs and URI creation logic, very hack right now
180 var fileUri, cssUrl, cssData, query, prefixUrl, fileCouldDirUrl, docRootUrl;
181 //
182 docRootUrl = this.application.ninja.coreIoApi.rootUrl+escape((this.application.ninja.documentController.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]).replace(/\/\//gi, '/'));
183 //TODO: Parse out relative URLs and map them to absolute
184 if (this._document.styleSheets[i].href.indexOf(this.application.ninja.coreIoApi.rootUrl) !== -1) {
185 //
186 cssUrl = this._document.styleSheets[i].href.split(this.application.ninja.coreIoApi.rootUrl)[1];
187 fileUri = this.application.ninja.coreIoApi.cloudData.root+cssUrl;
188 //TODO: Add error handling for reading file
189 cssData = this.application.ninja.coreIoApi.readFile({uri: fileUri});
190 //
191 var tag = this.iframe.contentWindow.document.createElement('style');
192 tag.setAttribute('type', 'text/css');
193 tag.setAttribute('data-ninja-uri', fileUri);
194 tag.setAttribute('data-ninja-file-url', cssUrl);
195 tag.setAttribute('data-ninja-file-read-only', JSON.parse(this.application.ninja.coreIoApi.isFileWritable({uri: fileUri}).content).readOnly);
196 tag.setAttribute('data-ninja-file-name', cssUrl.split('/')[cssUrl.split('/').length-1]);
197 //Copying attributes to maintain same properties as the <link>
198 for (var n in this._document.styleSheets[i].ownerNode.attributes) {
199 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') {
200 if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) {
201 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]);
202 } else {
203 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value);
204 }
205 }
206 }
207 //
208 fileCouldDirUrl = this._document.styleSheets[i].href.split(this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1])[0];
209
210 //TODO: Make public version of this.application.ninja.ioMediator.getNinjaPropUrlRedirect with dynamic ROOT
211 tag.innerHTML = cssData.content.replace(/url\(()(.+?)\1\)/g, detectUrl);
212
213 function detectUrl (prop) {
214 return prop.replace(/[^()\\""\\'']+/g, prefixUrl);;
215 }
216
217 function prefixUrl (url) {
218 if (url !== 'url') {
219 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)) {
220 url = fileCouldDirUrl+url;
221 }
222 }
223 return url;
224 }
225
226 //Looping through DOM to insert style tag at location of link element
227 query = this._templateDocument.html.querySelectorAll(['link']);
228 for (var j in query) {
229 if (query[j].href === this._document.styleSheets[i].href) {
230 //Disabling style sheet to reload via inserting in style tag
231 query[j].setAttribute('disabled', 'true');
232 //Inserting tag
233 this._templateDocument.head.insertBefore(tag, query[j]);
234 }
235 }
236 } else {
237 console.log('ERROR: Cross-Domain-Stylesheet detected, unable to load in Ninja');
238 //None local stylesheet, probably on a CDN (locked)
239 var tag = this.iframe.contentWindow.document.createElement('style');
240 tag.setAttribute('type', 'text/css');
241 tag.setAttribute('data-ninja-external-url', this._document.styleSheets[i].href);
242 tag.setAttribute('data-ninja-file-read-only', "true");
243 tag.setAttribute('data-ninja-file-name', this._document.styleSheets[i].href.split('/')[this._document.styleSheets[i].href.split('/').length-1]);
244 //Copying attributes to maintain same properties as the <link>
245 for (var n in this._document.styleSheets[i].ownerNode.attributes) {
246 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') {
247 if (this._document.styleSheets[i].ownerNode.attributes[n].value.indexOf(docRootUrl) !== -1) {
248 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value.split(docRootUrl)[1]);
249 } else {
250 tag.setAttribute(this._document.styleSheets[i].ownerNode.attributes[n].name, this._document.styleSheets[i].ownerNode.attributes[n].value);
251 }
252 }
253 }
254 /*
255
256 //TODO: Figure out cross-domain XHR issue, might need cloud to handle
257 var xhr = new XMLHttpRequest();
258 xhr.open("GET", this._document.styleSheets[i].href, true);
259 xhr.send();
260 //
261 if (xhr.readyState === 4) {
262 console.log(xhr);
263 }
264 //tag.innerHTML = xhr.responseText //xhr.response;
265 */
266 //Temp rule so it's registered in the array
267 tag.innerHTML = 'noRULEjustHACK{background: #000}';
268 //Disabling external style sheets
269 query = this._templateDocument.html.querySelectorAll(['link']);
270 for (var k in query) {
271 if (query[k].href === this._document.styleSheets[i].href) {
272
273 //TODO: Removed the temp insertion of the stylesheet
274 //because it wasn't the proper way to do it
275