summaryrefslogtreecommitdiff
path: root/docroot/classes/layouts/layout.primary.class.js
diff options
context:
space:
mode:
Diffstat (limited to 'docroot/classes/layouts/layout.primary.class.js')
-rwxr-xr-xdocroot/classes/layouts/layout.primary.class.js411
1 files changed, 411 insertions, 0 deletions
diff --git a/docroot/classes/layouts/layout.primary.class.js b/docroot/classes/layouts/layout.primary.class.js
new file mode 100755
index 0000000..87bc910
--- /dev/null
+++ b/docroot/classes/layouts/layout.primary.class.js
@@ -0,0 +1,411 @@
1/*
2 * Material Experience - Primary Card Layout Class
3 *
4 * EYEMG - Interactive Media Group
5 * Created by Mike Crute (mcrute@eyemg.com)
6 * Updated by Mike Crute (mcrute@eyemg.com) on 9/26/07
7 *
8 * WARNING: Here be dragons, OK so not as many as before but good luck you poor
9 * sap.
10 */
11
12Card.Layout.Primary = Class.create();
13Object.extend(Object.extend(Card.Layout.Primary.prototype, Card.Layout.prototype),
14{
15 /*
16 * Initialize the layout class
17 */
18 initialize: function(cframe, data, card)
19 {
20 this.cframe = cframe;
21 this.data = data;
22 this.card = card;
23 this.color = this.card.options.color;
24 this.hasResources = false;
25
26 var direction = data.template.replace(/narrow-/,'');
27 this.direction = direction ? direction : 'left';
28 this.oppositeDirection = (direction == 'left') ? 'right' : 'left';
29 },
30
31 /*
32 * Set the column content. This can be flash, an image or an iframe.
33 */
34 setColumn: function(url, direction, contTitle)
35 {
36 var content = Builder.node('div', { style: 'float: ' + this.oppositeDirection });
37 var myCol = direction + 'Col';
38
39 if (/swf$/.test(url)) // Flash
40 {
41 content.innerHTML = new SWFObject(url, 'cardFlash', 580, 479, 9, '#FFFFFF').getSWFHTML();
42 }
43 else if (/(png|gif|jpg|jpeg)$/.test(url)) // Image
44 {
45 content = Builder.node('img',
46 {
47 src: url,
48 alt: contTitle,
49 title: contTitle,
50 style: 'float: ' + this.oppositeDirection
51 });
52 }
53 else // iFrame
54 {
55 // Can't use DOM methods because IE is allergic
56 content.innerHTML = '<iframe ' +
57 'src = "' + url + '" ' +
58 'frameborder = "0" ' +
59 'scrolling = "auto" ' +
60 'width = "580" ' +
61 'height = "480" ' +
62 'id = "wide_content" ' +
63 'name = "wide_content" ' +
64 '></iframe>';
65 }
66
67 // We need to replace the content of the column if it exists to
68 // facilitate changing content later on (i.e. thumbnails)
69 if (typeof this[myCol] != 'undefined')
70 {
71 this.cframe.replaceChild(content, this[myCol]);
72 this[myCol] = content;
73 }
74 else
75 {
76 this[myCol] = this.cframe.appendChild(content);
77 }
78
79 },
80
81 /*
82 * Build the resource (more information) list.
83 */
84 getResourceList: function()
85 {
86 // Only run if we need to
87 if (!this.data.resources)
88 {
89 return;
90 }
91
92 var numResources = 0;
93 var iter = 0;
94 var limit = 5;
95 this.hasResources = true;
96
97 this.resourceContainer = this.contentArea.appendChild(
98 Builder.node('div',
99 [
100 Builder.node('h2', { style: 'color: ' + this.card.options.color }, Strings.moreInfo),
101 this.resources = Builder.node('ul', { className: 'resourceList' })
102 ]
103 ));
104
105 this.data.resources.each(function(item)
106 {
107 // Limit the number of allowable resources
108 if (typeof item == 'undefined' || ++iter > limit)
109 {
110 return;
111 }
112
113 numResources++;
114
115 this.resources.appendChild(Builder.node('li',
116 Builder.node('a',
117 {
118 href: item.link + '?entrypoint=DESIGNER',
119 target: '_new',
120 style: 'color: ' + this.color
121 }, item.title)
122 ));
123 }.bind(this));
124 },
125
126 /*
127 * Set the contents of the narrow column.
128 */
129 setHTML: function(content)
130 {
131 this.htmlDiv.innerHTML = content;
132 },
133
134 /*
135 * Setup the thumbnails.
136 */
137 getThumbnails: function()
138 {
139 // Only run if we need to
140 if (this.data.media.size() <= 1)
141 {
142 return;
143 }
144
145 var iter = 0;
146 var limit = 5; // Includes main media file
147 var lData = this.data.media;
148
149 this.thumbStrip = this.contentArea.appendChild(Builder.node('div', { className: 'thumbStrip' }));
150
151 // Add the main media file to the data array
152 lData.push(
153 {
154 thumb: this.data.contentWide[0].thumb,
155 url: this.data.contentWide[0].url
156 });
157
158 this.data.media.each(function(item)
159 {
160 // Limit the number of thumbnails
161 if (typeof item == 'undefined' || ++iter > limit)
162 {
163 return;
164 }
165
166 var mediaPiece = this.thumbStrip.appendChild(
167 Builder.node('img',
168 {
169 src: item.thumb,
170 className: 'mediaThumb'
171 })
172 );
173
174 Event.observe(mediaPiece, 'click', function()
175 {
176 this.setColumn(item.url, this.direction, '');
177 }.bindAsEventListener(this));
178 }.bind(this));
179 },
180
181 /*
182 * Clean up the data.
183 */
184 _cleanData: function()
185 {
186 var lData = this.data.contentNarrow[0].htmlContent;
187 this.data.contentNarrow[0].htmlContent = lData.replace(/<a/gi, '<a style="color: '+this.color+'"');
188 },
189
190 /*
191 * Calculate the heights of various interface elements for use in
192 * laying out the page.
193 */
194 _calculateHeights: function()
195 {
196 // This data structure will hold the heights of all the elements
197 // in the narrow column for use in dynamically calculating the
198 // layout of the column.
199 this.heightTable =
200 {
201 headline : this.headLine ? this.headLine.getHeight() : 0,
202 content : this.htmlDiv ? this.htmlDiv.getHeight() : 0,
203 thumbnails : this.thumbStrip ? this.thumbStrip.getHeight() : 0,
204 resources : this.resourceContainer ? this.resourceContainer.getHeight() : 0,
205 paddingFactor : !Prototype.Browser.IE ? 40 : 0
206 };
207
208 // If there is no headline IE comes up with a ridiculous height for some
209 // reason so we correct for that here.
210 if (Prototype.Browser.IE && this.data.contentNarrow[0].title.length == 0)
211 {
212 this.heightTable.headline = 0;
213 }
214
215 // A variety of exceptions/tweaks for IE6 found by testing every combination
216 // of layouts and finding the variance. There isn't much of another way to
217 // do it.
218 if (Prototype.Browser.IE)
219 {
220 this.heightTable.thumbnail += 2;
221 this.heightTable.content += 24;
222 }
223
224 if (Prototype.Browser.IE && this.resourceContainer)
225 {
226 this.heightTable.resources -= 30;
227 }
228
229 if (Prototype.Browser.IE && this.htmlDiv && this.thumbStrip && !this.resourceContainer)
230 {
231 this.heightTable.thumbnails += 10;
232 }
233
234
235 if (Prototype.Browser.IE && this.resourceContainer && !this.thumbStrip)
236 {
237 this.heightTable.resources += 70;
238 }
239
240 // Calculate the height available for content
241 this.heightTable.avaliableForContent = SME.sizes.innerCard.height - (
242 this.heightTable.headline +
243 this.heightTable.thumbnails +
244 this.heightTable.resources +
245 this.heightTable.paddingFactor
246 );
247 },
248
249 /*
250 * Setup the scroll bar on the wide content area.
251 */
252 _setupScroller: function()
253 {
254 // We only want to show the scroll bar if there is a need for it
255 if (this.heightTable.content < this.heightTable.avaliableForContent)
256 {
257 return;
258 }
259
260 this.contentArea.appendChild(
261 this.scrollCont = Builder.node('div',
262 {
263 style: 'border-left: 1px solid ' + this.card.options.color + ';' +
264 'width: 1px; right: 0px; position: absolute; ' +
265 'height:' + this.heightTable.avaliableForContent + 'px; ' +
266 'top: ' + (this.heightTable.headline + 10) + 'px;'
267 },
268
269 this.scrollBar = Builder.node('img',
270 {
271 src: 'images/pill.gif',
272 style: 'display: block; margin-left: -3px; cursor: move; ' +
273 'background: ' + this.card.options.color + ';'
274 })
275 ));
276
277 new Control.Slider(this.scrollBar, this.scrollCont,
278 {
279 axis: 'vertical',
280 range: $R(0, this.heightTable.content),
281
282 onSlide: function(value)
283 {
284 this.htmlDiv.scrollTop = value;
285 }.bind(this)
286 });
287
288 },
289
290 /*
291 * Main function to layout the card.
292 */
293 layout: function()
294 {
295 this._cleanData();
296
297 this.setColumn(this.data.contentWide[0].url, this.direction, this.data.contentWide[0].title);
298
299 this.contentArea = this.cframe.appendChild(
300 Builder.node('div', { className: 'narrowCol' },
301 this.headLine = Builder.node('h1', { style: 'color: ' + this.color }, this.data.contentNarrow[0].title)
302 )
303 );
304
305 // We've gotta set the width here otherwise the height
306 // calculations will be incorrect
307 this.htmlDiv = Builder.node('div', { style: 'width: 98%; overflow: hidden; width: 300px;' });
308
309 // Must set this early on otherwise there is no way to determine
310 // the actual height of the content div
311 this.setHTML(this.data.contentNarrow[0].htmlContent);
312 this.contentArea.appendChild(this.htmlDiv);
313
314 this.getResourceList();
315 this.getThumbnails();
316
317 // IE doesn't let prototype mess with the default object
318 // prototypes so we have to manually extend them. Sigh...
319 [
320 this.headLine,
321 this.htmlDiv,
322 this.thumbStrip,
323 this.resourceContainer,
324 this.contentArea
325 ].each(Element.extend);
326
327 // Set these styles up here or we get a -21px bug in our
328 // calculation code
329 this.contentArea.setStyle(
330 {
331 width: '310px',
332 position: 'absolute',
333 top: '0px'
334 });
335
336 this._calculateHeights();
337 this._setupScroller();
338
339 // We set this last, after all the height calculations are
340 // completed. That makes it a lot easier to work with.
341 this.htmlDiv.setStyle({ height: this.heightTable.avaliableForContent + 'px' });
342
343 // Webkit doesn't pad things correctly
344 if (this.direction == 'left')
345 {
346 this.contentArea.setStyle({ left: '10px' });
347 }
348 else
349 {
350 this.contentArea.setStyle({ right: '10px' });
351 }
352
353 // If this is an intro card do the intro card stuff.
354 if (this.data.template == 'intro')
355 {
356 this._doIntro();
357 }
358
359 return this;
360 },
361
362 /*
363 * Setup an intro card. Because intro cards aren't really that much
364 * different from a basic card and because class inheritance sucks in
365 * Prototype > 1.6 I'm just going to add this into here.
366 */
367 _doIntro: function()
368 {
369 this.contentArea.appendChild(Builder.node('div', { className: 'skipbox' },
370 this.skipLink = Builder.node('a', { href: '#tablehome', className: 'skiplink' },
371 [
372 Strings.skipButton,
373 Builder.node('img', { src: 'images/arrow_right_grey.gif', className: 'skipimg' })
374 ])
375 ));
376 },
377
378 /*
379 * Throw the card into a popup window for printing.
380 */
381 print: function()
382 {
383 var wind = window.open('', '', 'width=' + SME.sizes.innerCard.width + ',height=' + (SME.sizes.innerCard.height + 60));
384
385 with (wind)
386 {
387 with (document)
388 {
389 write('<html><head><style type="text/css">@import url(application.css); .narrowCol{top: 30px !important;}</style></head><body>');
390 write('<img src="images/logo.jpg" style="display: block; margin: 5px 0px 30px 5px;"/>');
391 write(this.cframe.innerHTML);
392 write('</body></html>');
393 close();
394 }
395
396 print();
397 close();
398 }
399
400 return true;
401 },
402
403 /*
404 * Debug the card layout. Generally this should be used to spot out
405 * data issues. But it could also be used for other debugging purposes.
406 */
407 _debug: function()
408 {
409
410 }
411}); \ No newline at end of file