diff options
Diffstat (limited to 'js/document/views/design.js')
-rwxr-xr-x | js/document/views/design.js | 155 |
1 files changed, 137 insertions, 18 deletions
diff --git a/js/document/views/design.js b/js/document/views/design.js index b23ebe78..c7aab1d7 100755 --- a/js/document/views/design.js +++ b/js/document/views/design.js | |||
@@ -23,11 +23,21 @@ exports.DesignDocumentView = Montage.create(BaseDocumentView, { | |||
23 | }, | 23 | }, |
24 | //////////////////////////////////////////////////////////////////// | 24 | //////////////////////////////////////////////////////////////////// |
25 | // | 25 | // |
26 | _template: { | ||
27 | value: null | ||
28 | }, | ||
29 | //////////////////////////////////////////////////////////////////// | ||
30 | // | ||
26 | _document: { | 31 | _document: { |
27 | value: null | 32 | value: null |
28 | }, | 33 | }, |
29 | //////////////////////////////////////////////////////////////////// | 34 | //////////////////////////////////////////////////////////////////// |
30 | // | 35 | // |
36 | _bodyFragment: { | ||
37 | value: null | ||
38 | }, | ||
39 | //////////////////////////////////////////////////////////////////// | ||
40 | // | ||
31 | _headFragment: { | 41 | _headFragment: { |
32 | value: null | 42 | value: null |
33 | }, | 43 | }, |
@@ -42,6 +52,11 @@ exports.DesignDocumentView = Montage.create(BaseDocumentView, { | |||
42 | value: null | 52 | value: null |
43 | }, | 53 | }, |
44 | //////////////////////////////////////////////////////////////////// | 54 | //////////////////////////////////////////////////////////////////// |
55 | //TODO: Remove usage | ||
56 | model: { | ||
57 | value: null | ||
58 | }, | ||
59 | //////////////////////////////////////////////////////////////////// | ||
45 | // | 60 | // |
46 | document: { | 61 | document: { |
47 | get: function() {return this._document;}, | 62 | get: function() {return this._document;}, |
@@ -65,19 +80,29 @@ exports.DesignDocumentView = Montage.create(BaseDocumentView, { | |||
65 | //////////////////////////////////////////////////////////////////// | 80 | //////////////////////////////////////////////////////////////////// |
66 | // | 81 | // |
67 | render: { | 82 | render: { |
68 | value: function (callback, template) {//TODO: Add support for templates | 83 | value: function (callback, template) { |
84 | //TODO: Remove, this is a temp patch for webRequest API gate | ||
85 | this.application.ninja.documentController._hackRootFlag = false; | ||
69 | //Storing callback for dispatch ready | 86 | //Storing callback for dispatch ready |
70 | this._callback = callback; | 87 | this._callback = callback; |
88 | this._template = template; | ||
71 | //Adding listener to know when template is loaded to then load user content | 89 | //Adding listener to know when template is loaded to then load user content |
72 | this.iframe.addEventListener("load", this.onTemplateLoad.bind(this), false); | 90 | this.iframe.addEventListener("load", this.onTemplateLoad.bind(this), false); |
73 | //TODO: Add source parameter and root (optional) | 91 | //TODO: Add source parameter and root (optional) |
74 | this.iframe.src = "js/document/templates/montage-web/index.html"; | 92 | if (template && template.type === 'banner' && template.size) { |
93 | this.iframe.src = "js/document/templates/banner/index.html"; | ||
94 | } else { | ||
95 | this.iframe.src = "js/document/templates/html/index.html"; | ||
96 | } | ||
75 | } | 97 | } |
76 | }, | 98 | }, |
77 | //////////////////////////////////////////////////////////////////// | 99 | //////////////////////////////////////////////////////////////////// |
78 | // | 100 | // |
79 | onTemplateLoad: { | 101 | onTemplateLoad: { |
80 | value: function (e) { | 102 | value: function (e) { |
103 | this.application.ninja.documentController._hackRootFlag = true; | ||
104 | //TODO: Add support to constructing URL with a base HREF | ||
105 | var basetag = this.content.document.getElementsByTagName('base'); | ||
81 | //Removing event | 106 | //Removing event |
82 | this.iframe.removeEventListener("load", this.onTemplateLoad.bind(this), false); | 107 | this.iframe.removeEventListener("load", this.onTemplateLoad.bind(this), false); |
83 | //TODO: Improve usage of this reference | 108 | //TODO: Improve usage of this reference |
@@ -88,22 +113,81 @@ exports.DesignDocumentView = Montage.create(BaseDocumentView, { | |||
88 | this.document.styleSheets[k].ownerNode.setAttribute('data-ninja-template', 'true'); | 113 | this.document.styleSheets[k].ownerNode.setAttribute('data-ninja-template', 'true'); |
89 | } | 114 | } |
90 | } | 115 | } |
91 | //Creating temp code fragement to load head | 116 | //Checking for a base URL |
92 | this._headFragment = this.document.createElement('head'); | 117 | if (basetag.length) { |
93 | //Adding event listener to know when head is ready, event only dispatched once when using innerHTML | 118 | if (basetag[basetag.length-1].getAttribute && basetag[basetag.length-1].getAttribute('href')) { |
94 | this._observer.head = new WebKitMutationObserver(this.insertHeadContent.bind(this)); | 119 | //Setting base HREF in model |
95 | this._observer.head.observe(this._headFragment, {childList: true}); | 120 | this.model.baseHref = basetag[basetag.length-1].getAttribute('href'); |
96 | //Inserting <head> HTML and parsing URLs via mediator method | 121 | } |
97 | this._headFragment.innerHTML = (this.content.head.replace(/\b(href|src)\s*=\s*"([^"]*)"/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator))).replace(/url\(([^"]*)(.+?)\1\)/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator)); | 122 | } |
98 | //Adding event listener to know when the body is ready and make callback (using HTML5 new DOM Mutation Events) | 123 | //Checking to content to be template |
99 | this._observer.body = new WebKitMutationObserver(this.bodyContentLoaded.bind(this)); | 124 | if (this._template) { |
100 | this._observer.body.observe(this.document.body, {childList: true}); | 125 | if (this._template.type === 'banner') { |
101 | //Inserting <body> HTML and parsing URLs via mediator method | 126 | //Loading contents into a fragment |
102 | this.document.body.innerHTML += '<ninjaloadinghack></ninjaloadinghack>'+(this.content.body.replace(/\b(href|src)\s*=\s*"([^"]*)"/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator))).replace(/url\(([^"]*)(.+?)\1\)/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator)); | 127 | this._bodyFragment = this.document.createElement('body'); |
128 | //Listening for content to be ready | ||
129 | this._observer.body = new WebKitMutationObserver(this.insertBannerContent.bind(this)); | ||
130 | this._observer.body.observe(this._bodyFragment, {childList: true}); | ||
131 | //Inserting <body> HTML and parsing URLs via mediator method | ||
132 | this._bodyFragment.innerHTML = '<ninjaloadinghack></ninjaloadinghack>'+(this.content.body.replace(/\b(href|src)\s*=\s*"([^"]*)"/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator))).replace(/url\(([^"]*)(.+?)\1\)/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator)); | ||
133 | } | ||
134 | } else { | ||
135 | //Creating temp code fragement to load head | ||
136 | this._headFragment = this.document.createElement('head'); | ||
137 | //Adding event listener to know when head is ready, event only dispatched once when using innerHTML | ||
138 | this._observer.head = new WebKitMutationObserver(this.insertHeadContent.bind(this)); | ||
139 | this._observer.head.observe(this._headFragment, {childList: true}); | ||
140 | //Inserting <head> HTML and parsing URLs via mediator method | ||
141 | this._headFragment.innerHTML = (this.content.head.replace(/\b(href|src)\s*=\s*"([^"]*)"/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator))).replace(/url\(([^"]*)(.+?)\1\)/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator)); | ||
142 | //Adding event listener to know when the body is ready and make callback (using HTML5 new DOM Mutation Events) | ||
143 | this._observer.body = new WebKitMutationObserver(this.bodyContentLoaded.bind(this)); | ||
144 | this._observer.body.observe(this.document.body, {childList: true}); | ||
145 | //Inserting <body> HTML and parsing URLs via mediator method | ||
146 | this.document.body.innerHTML += '<ninjaloadinghack></ninjaloadinghack>'+(this.content.body.replace(/\b(href|src)\s*=\s*"([^"]*)"/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator))).replace(/url\(([^"]*)(.+?)\1\)/g, this.application.ninja.ioMediator.getNinjaPropUrlRedirect.bind(this.application.ninja.ioMediator)); | ||
147 | //Copying attributes to maintain same properties as the <body> | ||
148 | for (var n in this.content.document.body.attributes) { | ||
149 | if (this.content.document.body.attributes[n].value) { | ||
150 | this.document.body.setAttribute(this.content.document.body.attributes[n].name, this.content.document.body.attributes[n].value); | ||
151 | } | ||
152 | } | ||
153 | //TODO: Add attribute copying for <HEAD> and <HTML> | ||
154 | } | ||
103 | } | 155 | } |
104 | }, | 156 | }, |
105 | //////////////////////////////////////////////////////////////////// | 157 | //////////////////////////////////////////////////////////////////// |
106 | // | 158 | // |
159 | insertBannerContent: { | ||
160 | value: function (e) { | ||
161 | //Getting first element in DOM (assumes it's root) | ||
162 | //TODO: Ensure wrapper logic is proper | ||
163 | var wrapper = this._bodyFragment.getElementsByTagName('*')[1], | ||
164 | banner = this._bodyFragment.getElementsByTagName('*')[2], | ||
165 | ninjaBanner = this.document.body.getElementsByTagName('ninja-content')[0], | ||
166 | ninjaWrapper = this.document.body.getElementsByTagName('ninja-viewport')[0]; | ||
167 | //Copying attributes to maintain same properties as the banner wrapper | ||
168 | for (var n in wrapper.attributes) { | ||
169 | if (wrapper.attributes[n].value) { | ||
170 | ninjaWrapper.setAttribute(wrapper.attributes[n].name, wrapper.attributes[n].value); | ||
171 | } | ||
172 | } | ||
173 | //Copying attributes to maintain same properties as the banner content | ||
174 | for (var n in banner.attributes) { | ||
175 | if (banner.attributes[n].value) { | ||
176 | ninjaBanner.setAttribute(banner.attributes[n].name, banner.attributes[n].value); | ||
177 | } | ||
178 | } | ||
179 | //Adjusting margin per size of document | ||
180 | this.document.head.getElementsByTagName('style')[0].innerHTML += '\n ninja-viewport {overflow: visible !important;} ninja-content, ninja-viewport {width: ' + this._template.size.width + 'px; height: ' + this._template.size.height + 'px;}'; | ||
181 | //Setting content in template | ||
182 | ninjaBanner.innerHTML = banner.innerHTML; | ||
183 | //Garbage collection | ||
184 | this._bodyFragment = null; | ||
185 | //Calling standard method to finish opening document | ||
186 | this.bodyContentLoaded(null); | ||
187 | } | ||
188 | }, | ||
189 | //////////////////////////////////////////////////////////////////// | ||
190 | // | ||
107 | insertHeadContent: { | 191 | insertHeadContent: { |
108 | value: function (e) { | 192 | value: function (e) { |
109 | //Removing event | 193 | //Removing event |
@@ -127,7 +211,7 @@ exports.DesignDocumentView = Montage.create(BaseDocumentView, { | |||
127 | //Removing event, only needed on initial load | 211 | //Removing event, only needed on initial load |
128 | this._observer.body.disconnect(); | 212 | this._observer.body.disconnect(); |
129 | this._observer.body = null; | 213 | this._observer.body = null; |
130 | //Removing loading container | 214 | //Removing loading container (should be removed) |
131 | this.document.body.removeChild(this.document.getElementsByTagName('ninjaloadinghack')[0]); | 215 | this.document.body.removeChild(this.document.getElementsByTagName('ninjaloadinghack')[0]); |
132 | //Getting style and link tags in document | 216 | //Getting style and link tags in document |
133 | var stags = this.document.getElementsByTagName('style'), | 217 | var stags = this.document.getElementsByTagName('style'), |
@@ -141,8 +225,12 @@ exports.DesignDocumentView = Montage.create(BaseDocumentView, { | |||
141 | for (i = 0; i < ltags.length; i++) { | 225 | for (i = 0; i < ltags.length; i++) { |
142 | // | 226 | // |
143 | if (ltags[i].href) { | 227 | if (ltags[i].href) { |
144 | //TODO: Verify this works for tags in body as well (working in head) | 228 | //Inseting <style> right above of <link> to maintain hierarchy |
145 | this.document.head.insertBefore(this.getStyleTagFromCssFile(ltags[i]), ltags[i]) || this.document.body.insertBefore(this.getStyleTagFromCssFile(ltags[i]), ltags[i]); | 229 | try { |
230 | this.document.head.insertBefore(this.getStyleTagFromCssFile(ltags[i]), ltags[i]) | ||
231 | } catch (e) { | ||
232 | this.document.body.insertBefore(this.getStyleTagFromCssFile(ltags[i]), ltags[i]); | ||
233 | } | ||
146 | //Disabling tag once it has been reloaded | 234 | //Disabling tag once it has been reloaded |
147 | ltags[i].setAttribute('disabled', 'true'); | 235 | ltags[i].setAttribute('disabled', 'true'); |
148 | } else { | 236 | } else { |
@@ -230,7 +318,7 @@ exports.DesignDocumentView = Montage.create(BaseDocumentView, { | |||
230 | initWebGl: { | 318 | initWebGl: { |
231 | value: function (scripttags) { | 319 | value: function (scripttags) { |
232 | // | 320 | // |
233 | var i, n, webgldata; | 321 | var n, webgldata; |
234 | //Setting the iFrame property for reference in helper class |