flexlayout-rails 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ module("Feature detection");
2
+
3
+ test("modernizr cssregions detection", function() {
4
+ notEqual(Modernizr.cssregions, undefined);
5
+ });
6
+
7
+ test("the browser isn't compatible with the css regions", function() {
8
+ equal(Modernizr.cssregions, false);
9
+ });
@@ -0,0 +1,43 @@
1
+ $(function(){
2
+ module("Layout");
3
+
4
+ $("#article").regions(["#article-region-1", "#article-region-2", "#article-region-3"]);
5
+
6
+ test("hide flow source", function() {
7
+ equal($('#article').css("display"), "none");
8
+ });
9
+
10
+ test("regions have content", function() {
11
+ notEqual($('.article-region').text(), "");
12
+ });
13
+
14
+ test("regions have different content", function() {
15
+ notEqual($('#article-region-1').text(), $('#article-region-2').text());
16
+ });
17
+
18
+ test("text in the first region is matching", function() {
19
+ var expected = /1Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod */;
20
+ ok(
21
+ expected.test($('#article-region-1').text()),
22
+ "is 1Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
23
+ );
24
+ });
25
+
26
+
27
+ // alternative method: use only a target jquery selector:
28
+ $("#alternative-article").regions('.alternative-region');
29
+
30
+ test("alternative method with jquery selector", function(){
31
+ var expected = /Lorem ipsum dolor sit amet, consectetur adipiscing elit. */;
32
+ ok(
33
+ expected.test($('.alternative-region:first').text()),
34
+ 'is Lorem ipsum dolor sit amet, consectetur adipisicing elit. …'
35
+ )
36
+ });
37
+
38
+
39
+ // handling oversized elements
40
+ test("oversized object visible", function(){
41
+ equal($('.alternative-region img#oversized').length, 1);
42
+ });
43
+ });
File without changes
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'flexie-rails'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,6 @@
1
+ // test if the CSS regions support is enabled
2
+ // http://dev.w3.org/csswg/css3-regions/
3
+
4
+ Modernizr.addTest( "cssregions",function(){
5
+ return Modernizr.testAllProps("flow");
6
+ });
@@ -0,0 +1,2039 @@
1
+ /*
2
+ File: flexie.js
3
+
4
+ About: Version
5
+ 1.0.3
6
+
7
+ Project: Flexie
8
+
9
+ Description:
10
+ Legacy support for the CSS3 Flexible Box Model
11
+
12
+ License:
13
+ The MIT License
14
+
15
+ Copyright (c) 2010 Richard Herrera
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy
18
+ of this software and associated documentation files (the "Software"), to deal
19
+ in the Software without restriction, including without limitation the rights
20
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+ copies of the Software, and to permit persons to whom the Software is
22
+ furnished to do so, subject to the following conditions:
23
+
24
+ The above copyright notice and this permission notice shall be included in
25
+ all copies or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33
+ THE SOFTWARE.
34
+ */
35
+
36
+ /*
37
+ Class: Flexie
38
+ Scoped to the Flexie Global Namespace
39
+ */
40
+
41
+ /*jslint evil: true, regexp: false, plusplus: false */
42
+ /*global window, document */
43
+
44
+
45
+ var flexiebox = function(selector, options) {
46
+ return new Flexie.box($(selector), options)
47
+ }
48
+
49
+ var Flexie = (function (win, doc) {
50
+
51
+ // Scope public properties
52
+ var FLX = {},
53
+
54
+ // Each Flexie-modified DOM node gets a unique identifier
55
+ FLX_DOM_ID = 0,
56
+ FLX_DOM_ATTR = "data-flexie-id",
57
+ FLX_PARENT_ATTR = "data-flexie-parent",
58
+
59
+ // Store support for flexbox
60
+ SUPPORT,
61
+
62
+ // Store reference to engine
63
+ ENGINE,
64
+
65
+ ENGINES = {
66
+ "NW" : {
67
+ s : "*.Dom.select"
68
+ },
69
+ "DOMAssistant" : {
70
+ s : "*.$",
71
+ m : "*.DOMReady"
72
+ },
73
+ "Prototype" : {
74
+ s : "$$",
75
+ m : "document.observe",
76
+ p : "dom:loaded",
77
+ c : "document"
78
+ },
79
+ "YAHOO" : {
80
+ s : "*.util.Selector.query",
81
+ m : "*.util.Event.onDOMReady",
82
+ c : "*.util.Event"
83
+ },
84
+ "MooTools" : {
85
+ s : "$$",
86
+ m : "window.addEvent",
87
+ p : "domready"
88
+ },
89
+ "Sizzle" : {
90
+ s : "*"
91
+ },
92
+ "jQuery" : {
93
+ s : "*",
94
+ m : "*(document).ready"
95
+ },
96
+ "dojo" : {
97
+ s : "*.query",
98
+ m : "*.addOnLoad"
99
+ }
100
+ },
101
+
102
+ // Store reference to library
103
+ LIBRARY,
104
+
105
+ // Regular Expressions
106
+ PIXEL = /^-?\d+(?:px)?$/i,
107
+ NUMBER = /^-?\d/,
108
+ SIZES = /width|height|margin|padding|border/,
109
+ MSIE = /(msie) ([\w.]+)/,
110
+ WHITESPACE_CHARACTERS = /\t|\n|\r/g,
111
+ RESTRICTIVE_PROPERTIES = /^max\-([a-z]+)/,
112
+ PROTOCOL = /^https?:\/\//i,
113
+ LEADINGTRIM = /^\s\s*/,
114
+ TRAILINGTRIM = /\s\s*$/,
115
+ ONLY_WHITESPACE = /^\s*$/,
116
+ CSS_SELECTOR = /\s?(\#|\.|\[|\:(\:)?[^first\-(line|letter)|before|after]+)/g,
117
+
118
+ // String constants
119
+ EMPTY_STRING = "",
120
+ SPACE_STRING = " ",
121
+ PLACEHOLDER_STRING = "$1",
122
+ PADDING_RIGHT = "paddingRight",
123
+ PADDING_BOTTOM = "paddingBottom",
124
+ PADDING_LEFT = "paddingLeft",
125
+ PADDING_TOP = "paddingTop",
126
+ BORDER_RIGHT = "borderRightWidth",
127
+ BORDER_BOTTOM = "borderBottomWidth",
128
+ BORDER_LEFT = "borderLeftWidth",
129
+ BORDER_TOP = "borderTopWidth",
130
+ HORIZONTAL = "horizontal",
131
+ VERTICAL = "vertical",
132
+ INLINE_AXIS = "inline-axis",
133
+ BLOCK_AXIS = "block-axis",
134
+ INHERIT = "inherit",
135
+ LEFT = "left",
136
+
137
+ END_MUSTACHE = "}",
138
+
139
+ PREFIXES = " -o- -moz- -ms- -webkit- -khtml- ".split(SPACE_STRING),
140
+
141
+ DEFAULTS = {
142
+ orient : HORIZONTAL,
143
+ align : "stretch",
144
+ direction : INHERIT,
145
+ pack : "start"
146
+ },
147
+
148
+ // Global reference objects
149
+ FLEX_BOXES = [],
150
+ POSSIBLE_FLEX_CHILDREN = [],
151
+ DOM_ORDERED,
152
+
153
+ RESIZE_LISTENER,
154
+
155
+ // Minification optimizations
156
+ TRUE = true,
157
+ FALSE = false,
158
+ NULL = null,
159
+ UNDEFINED,
160
+
161
+ // If IE, which version?
162
+ BROWSER = {
163
+ IE : (function () {
164
+ var ie, ua = win.navigator.userAgent,
165
+ match = (MSIE).exec(ua.toLowerCase());
166
+
167
+ if (match) {
168
+ ie = parseInt(match[2], 10);
169
+ }
170
+
171
+ return ie;
172
+ }())
173
+ },
174
+
175
+ /*
176
+ selectivizr v1.0.0 - (c) Keith Clark, freely distributable under the terms
177
+ of the MIT license.
178
+
179
+ selectivizr.com
180
+ */
181
+ selectivizrEngine;
182
+
183
+ function trim (string) {
184
+ if (string) {
185
+ string = string.replace(LEADINGTRIM, EMPTY_STRING).replace(TRAILINGTRIM, EMPTY_STRING);
186
+ }
187
+
188
+ return string;
189
+ }
190
+
191
+ // --[ determineSelectorMethod() ]--------------------------------------
192
+ // walks through the engines object testing for an suitable
193
+ // selector engine.
194
+
195
+ // Moving outside Selectivizr scope because detection is needed before running selectivizrEngine
196
+ function determineSelectorMethod() {
197
+ // compatiable selector engines in order of CSS3 support
198
+ var engines = ENGINES, method,
199
+ engine, obj;
200
+
201
+ for (engine in engines) {
202
+ if (engines.hasOwnProperty(engine)) {
203
+ obj = engines[engine];
204
+
205
+ if (win[engine] && !method) {
206
+ method = eval(obj.s.replace("*", engine));
207
+
208
+ if (method) {
209
+ ENGINE = engine;
210
+ break;
211
+ }
212
+ }
213
+ }
214
+ }
215
+
216
+ return method;
217
+ }
218
+
219
+ // Event handler for onload/onresize events
220
+ function addEvent(type, func) {
221
+ type = "on" + type;
222
+ var oldevent = win[type];
223
+
224
+ if (typeof win[type] !== "function") {
225
+ win[type] = func;
226
+ } else {
227
+ win[type] = function () {
228
+ if (oldevent) {
229
+ oldevent();
230
+ }
231
+ func();
232
+ };
233
+ }
234
+ }
235
+
236
+ function attachLoadMethod(handler) {
237
+ if (!ENGINE) {
238
+ LIBRARY = determineSelectorMethod();
239
+ }
240
+
241
+ // compatiable selector engines in order of CSS3 support
242
+ var engines = ENGINES,
243
+ method, caller, args,
244
+ engine, obj;
245
+
246
+ for (engine in engines) {
247
+ if (engines.hasOwnProperty(engine)) {
248
+ obj = engines[engine];
249
+
250
+ if (win[engine] && !method && obj.m) {
251
+ method = eval(obj.m.replace("*", engine));
252
+ caller = obj.c ? eval(obj.c.replace("*", engine)) : win;
253
+ args = [];
254
+
255
+ if (method && caller) {
256
+ if (obj.p) {
257
+ args.push(obj.p);
258
+ }
259
+ args.push(handler);
260
+ method.apply(caller, args);
261
+ break;
262
+ }
263
+ }
264
+ }
265
+ }
266
+
267
+ if (!method) {
268
+ addEvent("load", handler);
269
+ }
270
+ }
271
+
272
+ function buildSelector (node) {
273
+ var selector = node.nodeName.toLowerCase();
274
+
275
+ if (node.id) {
276
+ selector += "#" + node.id;
277
+ } else if (node.FLX_DOM_ID) {
278
+ selector += "[" + FLX_DOM_ATTR + "='" + node.FLX_DOM_ID + "']";
279
+ }
280
+
281
+ return selector;
282
+ }
283
+
284
+ function setFlexieId (node) {
285
+ if (!node.FLX_DOM_ID) {
286
+ FLX_DOM_ID = (FLX_DOM_ID + 1);
287
+
288
+ node.FLX_DOM_ID = FLX_DOM_ID;
289
+ node.setAttribute(FLX_DOM_ATTR, node.FLX_DOM_ID);
290
+ }
291
+ }
292
+
293
+ function buildSelectorTree(text) {
294
+ var rules = [], ruletext, rule,
295
+ match, selector, proptext, splitprop, properties,
296
+ i, j, x;
297
+
298
+ // Tabs, Returns
299
+ text = text.replace(WHITESPACE_CHARACTERS, EMPTY_STRING);
300
+
301
+ // Leading / Trailing Whitespace
302
+ text = text.replace(/\s?(\{|\:|\})\s?/g, PLACEHOLDER_STRING);
303
+
304
+ ruletext = text.split(END_MUSTACHE);
305
+
306
+ for (i in ruletext) {
307
+ if (ruletext.hasOwnProperty(i)) {
308
+ text = ruletext[i];
309
+
310
+ if (text) {
311
+ rule = [text, END_MUSTACHE].join(EMPTY_STRING);
312
+
313
+ match = (/(\@media[^\{]+\{)?(.*)\{(.*)\}/).exec(rule);
314
+
315
+ if (match && match[3]) {
316
+ selector = match[2];
317
+ proptext = match[3].split(";");
318
+ properties = [];
319
+
320
+ for (j in proptext) {
321
+ if (proptext.hasOwnProperty(j)) {
322
+ x = proptext[j];
323
+ splitprop = x.split(":");
324
+
325
+ if (splitprop.length && splitprop[1]) {
326
+ properties.push({
327
+ property : splitprop[0],
328
+ value : splitprop[1]
329
+ });
330
+ }
331
+ }
332
+ }
333
+
334
+ if (selector && properties.length) {
335
+ rules.push({
336
+ selector : selector,
337
+ properties : properties
338
+ });
339
+ }
340
+ }
341
+ }
342
+ }
343
+ }
344
+
345
+ return rules;
346
+ }
347
+
348
+ function findFlexboxElements(rules) {
349
+ var selectors, properties,
350
+ property, value, shortProp,
351
+ selectorSplit = /\s?,\s?/,
352
+ createUniqueObject, addRules, key,
353
+ uniqueChildren = {}, uniqueBoxes = {},
354
+ i, j, rule, k, l, selector, m, n, prop;
355
+
356
+ createUniqueObject = function (selector, rules, prop, value) {
357
+ var unique, i, j, rule;
358
+
359
+ unique = {
360
+ selector : trim(selector),
361
+ properties : []
362
+ };
363
+
364
+ for (i = 0, j = rules.properties.length; i < j; i++) {
365
+ rule = rules.properties[i];
366
+
367
+ unique.properties.push({
368
+ property : trim(rule.property),
369
+ value : trim(rule.value)
370
+ });
371
+ }
372
+
373
+ if (prop && value) {
374
+ unique[prop] = value;
375
+ }
376
+
377
+ return unique;
378
+ };
379
+
380
+ addRules = function (selector, rules, prop, value) {
381
+ var box = (prop && value) ? uniqueChildren[selector] : uniqueBoxes[selector],
382
+ exists, x, i, j, rule, k, l;
383
+
384
+ if (box) {
385
+ for (i = 0, j = rules.properties.length; i < j; i++) {
386
+ rule = rules.properties[i];
387
+
388
+ for (k = 0, l = box.properties.length; k < l; k++) {
389
+ x = box.properties[k];
390
+
391
+ if (rule.property === x.property) {
392
+ exists = k;
393
+ return false;
394
+ }
395
+ }
396
+
397
+ if (exists) {
398
+ box.properties[exists] = rule;
399
+ } else {
400
+ box.properties.push(rule);
401
+ }
402
+ }
403
+
404
+ if (prop && value) {
405
+ box[prop] = value;
406
+ }
407
+ } else {
408
+ if (prop && value) {
409
+ uniqueChildren[selector] = createUniqueObject(selector, rules, prop, value);
410
+ } else {
411
+ uniqueBoxes[selector] = createUniqueObject(selector, rules, NULL, NULL);
412
+ }
413
+ }
414
+ };
415
+
416
+ for (i = 0, j = rules.length; i < j; i++) {
417
+ rule = rules[i];
418
+
419
+ selectors = trim(rule.selector).replace(selectorSplit, ",").split(selectorSplit);
420
+
421
+ for (k = 0, l = selectors.length; k < l; k++) {
422
+ selector = trim(selectors[k]);
423
+ properties = rule.properties;
424
+
425
+ for (m = 0, n = properties.length; m < n; m++) {
426
+ prop = properties[m];
427
+ property = trim(prop.property);
428
+ value = trim(prop.value);
429
+
430
+ if (property) {
431
+ shortProp = property.replace("box-", EMPTY_STRING);
432
+
433
+ switch (shortProp) {
434
+ case "display" :
435
+ if (value === "box") {
436
+ addRules(selector, rule, NULL, NULL);
437
+ }
438
+ break;
439
+
440
+ case "orient" :
441
+ case "align" :
442
+ case "direction" :
443
+ case "pack" :
444
+ addRules(selector, rule, NULL, NULL);
445
+ break;
446
+
447
+ case "flex" :
448
+ case "flex-group" :
449
+ case "ordinal-group" :
450
+ addRules(selector, rule, shortProp, value);
451
+ break;
452
+ }
453
+ }
454
+ }
455
+ }
456
+ }
457
+
458
+ for (key in uniqueBoxes) {
459
+ if (uniqueBoxes.hasOwnProperty(key)) {
460
+ FLEX_BOXES.push(uniqueBoxes[key]);
461
+ }
462
+ }
463
+
464
+ for (key in uniqueChildren) {
465
+ if (uniqueChildren.hasOwnProperty(key)) {
466
+ POSSIBLE_FLEX_CHILDREN.push(uniqueChildren[key]);
467
+ }
468
+ }
469
+
470
+ return {
471
+ boxes : FLEX_BOXES,
472
+ children : POSSIBLE_FLEX_CHILDREN
473
+ };
474
+ }
475
+
476
+ function matchFlexChildren(parent, lib, possibleChildren) {
477
+ var caller, unique, matches = [],
478
+ i, j, child,
479
+ k, l, node,
480
+ key;
481
+
482
+ for (i = 0, j = possibleChildren.length; i < j; i++) {
483
+ child = possibleChildren[i];
484
+
485
+ if (child.selector) {
486
+ caller = lib(child.selector);
487
+ caller = caller[0] ? caller : [caller];
488
+
489
+ if (caller[0]) {
490
+
491
+ for (k = 0, l = caller.length; k < l; k++) {
492
+ node = caller[k];
493
+
494
+ if (node.nodeName !== UNDEFINED) {
495
+ switch (node.nodeName.toLowerCase()) {
496
+ case "script" :
497
+ case "style" :
498
+ case "link" :
499
+ break;
500
+
501
+ default :
502
+ if (node.parentNode === parent) {
503
+ // Flag each unique node with FLX_DOM_ID
504
+ setFlexieId(node);
505
+
506
+ unique = {};
507
+
508
+ for (key in child) {
509
+ if (child.hasOwnProperty(key)) {
510
+ unique[key] = child[key];
511
+ }
512
+ }
513
+
514
+ unique.match = node;
515
+ matches.push(unique);
516
+ }
517
+ break;
518
+ }
519
+ }
520
+ }
521
+ }
522
+ } else {
523
+ // Flag each unique node with FLX_DOM_ID
524
+ setFlexieId(child);
525
+
526
+ matches.push({
527
+ match : child,
528
+ selector : buildSelector(child)
529
+ });
530
+ }
531
+ }
532
+
533
+ return matches;
534
+ }
535
+
536
+ function getParams(params) {
537
+ var key;
538
+
539
+ for (key in params) {
540
+ if (params.hasOwnProperty(key)) {
541
+ params[key] = params[key] || DEFAULTS[key];
542
+ }
543
+ }
544
+
545
+ return params;
546
+ }
547
+
548
+ function buildFlexieCall(flexers) {
549
+ var selector, properties, property, value, shortProp,
550
+ display, orient, align, direction, pack,
551
+ lib, caller, children,
552
+ box, params, flexboxes = {},
553
+ match, childMatch, nestedFlexboxes,
554
+ flexieParentSelector = "[" + FLX_PARENT_ATTR + "]",
555
+ i, j, flex, k, l, prop,
556
+ target, key, m, n, child, o, p, existing;
557
+
558
+ // No boxflex? No dice.
559
+ if (!flexers) {
560
+ return;
561
+ }
562
+
563
+ for (i = 0, j = flexers.boxes.length; i < j; i++) {
564
+ flex = flexers.boxes[i];
565
+ flex.selector = trim(flex.selector);
566
+
567
+ selector = flex.selector;
568
+ properties = flex.properties;
569
+
570
+ display = orient = align = direction = pack = NULL;
571
+
572
+ for (k = 0, l = properties.length; k < l; k++) {
573
+ prop = properties[k];
574
+
575
+ property = trim(prop.property);
576
+ value = trim(prop.value);
577
+
578
+ if (property) {
579
+ shortProp = property.replace("box-", EMPTY_STRING);
580
+
581
+ switch (shortProp) {
582
+ case "display" :
583
+ if (value === "box") {
584
+ display = value;
585
+ }
586
+ break;
587
+
588
+ case "orient" :
589
+ orient = value;
590
+ break;
591
+
592
+ case "align" :
593
+ align = value;
594
+ break;
595
+
596
+ case "direction" :
597
+ direction = value;
598
+ break;
599
+
600
+ case "pack" :
601
+ pack = value;
602
+ break;
603
+ }
604
+ }
605
+ }
606
+
607
+ // Determine library
608
+ lib = LIBRARY;
609
+
610
+ // Call it.
611
+ caller = lib(flex.selector);
612
+
613
+ // In an array?
614
+ caller = caller[0] ? caller : [caller];
615
+
616
+ for (k = 0, l = caller.length; k < l; k++) {
617
+ target = caller[k];
618
+
619
+ // If is DOM object
620
+ if (target.nodeType) {
621
+ // Flag each unique node with FLX_DOM_ID
622
+ setFlexieId(target);
623
+
624
+ // Find possible child node matches
625
+ children = matchFlexChildren(target, lib, flexers.children);
626
+
627
+ // Find any nested flexbox elements
628
+ nestedFlexboxes = selector + " " + flexieParentSelector;
629
+
630
+ // Make sure there is some value associated with box properties
631
+ params = {
632
+ target : target,
633
+ selector : selector,
634
+ properties : properties,
635
+ children : children,
636
+ display : display,
637
+ orient : orient,
638
+ align : align,
639
+ direction: direction,
640
+ pack : pack,
641
+ nested : nestedFlexboxes
642
+ };
643
+
644
+ match = flexboxes[target.FLX_DOM_ID];
645
+
646
+ if (match) {
647
+ for (key in params) {
648
+ if (params.hasOwnProperty(key)) {
649
+ value = params[key];
650
+
651
+ switch (key) {
652
+ case "selector" :
653
+ if (value && !(new RegExp(value).test(match[key]))) {
654
+ match[key] += ", " + value;
655
+ }
656
+ break;
657
+
658
+ case "children" :
659
+ for (m = 0, n = params[key].length; m < n; m++) {
660
+ child = params[key][m];
661
+ childMatch = FALSE;
662
+
663
+ for (o = 0, p = match[key].length; o < p; o++) {
664
+ existing = match[key][o];
665
+
666
+ if (child.match.FLX_DOM_ID === existing.match.FLX_DOM_ID) {
667
+ childMatch = TRUE;
668
+ }
669
+ }
670
+
671
+ if (!childMatch) {
672
+ match[key].push(child);
673
+ }
674
+ }
675
+ break;
676
+
677
+ default :
678
+ if (value) {
679
+ match[key] = value;
680
+ }
681
+ break;
682
+ }
683
+ }
684
+ }
685
+ } else {
686
+ flexboxes[target.FLX_DOM_ID] = getParams(params);
687
+ flexboxes[target.FLX_DOM_ID].target.setAttribute(FLX_PARENT_ATTR, TRUE);
688
+ }
689
+ }
690
+ }
691
+ }
692
+
693
+ DOM_ORDERED = LIBRARY(flexieParentSelector);
694
+ FLEX_BOXES = {};
695
+
696
+ for (i = 0, j = DOM_ORDERED.length; i < j; i++) {
697
+ target = DOM_ORDERED[i];
698
+
699
+ FLEX_BOXES[target.FLX_DOM_ID] = flexboxes[target.FLX_DOM_ID];
700
+ }
701
+
702
+ // Loop through each match, initialize constructor
703
+ for (key in FLEX_BOXES) {
704
+ if (FLEX_BOXES.hasOwnProperty(key)) {
705
+ flex = FLEX_BOXES[key];
706
+
707
+ // One final check to ensure each flexbox has a display property
708
+ if (flex.display === "box") {
709
+ // Constructor
710
+ box = new FLX.box(flex);
711
+ }
712
+ }
713
+ }
714
+ }
715
+
716
+ function calcPx(element, props, dir) {
717
+ var dim = dir.replace(dir.charAt(0), dir.charAt(0).toUpperCase()),
718
+ value = element["offset" + dim] || 0,
719
+ i, j, prop;
720
+
721
+ if (value) {
722
+ for (i = 0, j = props.length; i < j; i++) {
723
+ prop = parseFloat(element.currentStyle[props[i]]);
724
+
725
+ if (!isNaN(prop)) {
726
+ value -= prop;
727
+ }
728
+ }
729
+ }
730
+
731
+ return value;
732
+ }
733
+
734
+ function getTrueValue(element, name) {
735
+ var left, rsLeft,
736
+ ret = element.currentStyle && element.currentStyle[name],
737
+ style = element.style;
738
+
739
+ if (!PIXEL.test(ret) && NUMBER.test(ret)) {
740
+
741
+ // Remember the original values
742
+ left = style.left;
743
+ rsLeft = element.runtimeStyle.left;
744
+
745
+ // Put in the new values to get a computed value out
746
+ element.runtimeStyle.left = element.currentStyle.left;
747
+ style.left = ret || 0;
748
+ ret = style.pixelLeft + "px";
749
+
750
+ // Revert the changed values
751
+ style.left = left || 0;
752
+ element.runtimeStyle.left = rsLeft;
753
+ }
754
+
755
+ return ret;
756
+ }
757
+
758
+ function unAuto(element, prop, name) {
759
+ var props;
760
+
761
+ switch (name) {
762
+ case "width" :
763
+ props = [PADDING_LEFT, PADDING_RIGHT, BORDER_LEFT, BORDER_RIGHT];
764
+ prop = calcPx(element, props, name);
765
+ break;
766
+
767
+ case "height" :
768
+ props = [PADDING_TOP, PADDING_BOTTOM, BORDER_TOP, BORDER_BOTTOM];
769
+ prop = calcPx(element, props, name);
770
+ break;
771
+
772
+ default :
773
+ prop = getTrueValue(element, name);
774
+ break;
775
+ }
776
+
777
+ return prop;
778
+ }
779
+
780
+ function getPixelValue(element, prop, name) {
781
+ if (PIXEL.test(prop)) {
782
+ return prop;
783
+ }
784
+
785
+ // if property is auto, do some messy appending
786
+ if (prop === "auto" || prop === "medium") {
787
+ prop = unAuto(element, prop, name);
788
+ } else {
789
+ prop = getTrueValue(element, name);
790
+ }
791
+
792
+ return prop;
793
+ }
794
+
795
+ function getComputedStyle(element, property, returnAsInt) {
796
+ var value;
797
+
798
+ if (element === UNDEFINED) {
799
+ return;
800
+ }
801
+
802
+ if (win.getComputedStyle) {
803
+ value = win.getComputedStyle(element, NULL)[property];
804
+ } else {
805
+ if (SIZES.test(property)) {
806
+ value = getPixelValue(element, (element && element.currentStyle) ? element.currentStyle[property] : 0, property);
807
+ } else {
808
+ value = element.currentStyle[property];
809
+ }
810
+ }
811
+
812
+ if (returnAsInt) {
813
+ value = parseInt(value, 10);
814
+
815
+ if (isNaN(value)) {
816
+ value = 0;
817
+ }
818
+ }
819
+
820
+ return value;
821
+ }
822
+
823
+ function clientWidth(element) {
824
+ return element.innerWidth || element.clientWidth;
825
+ }
826
+
827
+ function clientHeight(element) {
828
+ return element.innerHeight || element.clientHeight;
829
+ }
830
+
831
+ function appendProperty(target, prop, value, prefixName) {
832
+ var cssText = [],
833
+ i, j, prefix;
834
+
835
+ for (i = 0, j = PREFIXES.length; i < j; i++) {
836
+ prefix = PREFIXES[i];
837
+ cssText.push((prefixName ? prefix : EMPTY_STRING) + prop + ":" + (!prefixName ? prefix : EMPTY_STRING) + value);
838
+ }
839
+
840
+ target.style.cssText += cssText.join(";");
841
+ return target;
842
+ }
843
+
844
+ function appendPixelValue(target, prop, value) {
845
+ var targets = target && target[0] ? target : [target],
846
+ i, j;
847
+
848
+ for (i = 0, j = targets.length; i < j; i++) {
849
+ target = targets[i];
850
+
851
+ if (target && target.style) {
852
+ target.style[prop] = (value ? (value + "px") : EMPTY_STRING);
853
+ }
854
+ }
855
+ }
856
+
857
+ function calculateSpecificity (selector) {
858
+ var selectorGrid, matrix, total,
859
+ i, j, chunk;
860
+
861
+ selectorGrid = selector.replace(CSS_SELECTOR, function (e, f) {
862
+ return "%" + f;
863
+ }).replace(/\s|\>|\+|\~/g, "%").split(/%/g);
864
+
865
+ matrix = {
866
+ _id : 100,
867
+ _class : 10,
868
+ _tag : 1
869
+ };
870
+
871
+ // Start with rule index position
872
+ total = 0;
873
+
874
+ // Add each selector value to total.
875
+ for (i = 0, j = selectorGrid.length; i < j; i++) {
876
+ chunk = selectorGrid[i];
877
+
878
+ if ((/#/).test(chunk)) {
879
+ total += matrix._id;
880
+ } else if ((/\.|\[|\:/).test(chunk)) {
881
+ total += matrix._class;
882
+ } else if ((/[a-zA-Z]+/).test(chunk)) {
883
+ total += matrix._tag;
884
+ }
885
+ }
886
+
887
+ return total;
888
+ }
889
+
890
+ function filterDuplicates (matches, children, type) {
891
+ var filteredMatches = [], exists,
892
+ spec = (type ? "ordinal" : "flex") + "Specificity",
893
+ i, j, x, k, l, f;
894
+
895
+ for (i = 0, j = matches.length; i < j; i++) {
896
+ x = matches[i];
897
+
898
+ if ((!type && x.flex) || (type && x["ordinal-group"])) {
899
+ x[spec] = x[spec] || calculateSpecificity(x.selector);
900
+
901
+ exists = FALSE;
902
+
903
+ for (k = 0, l = filteredMatches.length; k < l; k++) {
904
+ f = filteredMatches[k];
905
+
906
+ if (f.match === x.match) {
907
+ if (f[spec] < x[spec]) {
908
+ filteredMatches[j] = x;
909
+ }
910
+
911
+ exists = TRUE;
912
+ return FALSE;
913
+ }
914
+ }
915
+
916
+ if (!exists) {
917
+ filteredMatches.push(x);
918
+ }
919
+ }
920
+ }
921
+
922
+ return filteredMatches;
923
+ }
924
+
925
+ function createMatchMatrix(matches, children, type) {
926
+ var groups = {}, keys = [], totalRatio = 0,
927
+ group, order = "ordinal-group",
928
+ BoxOrdinalAttr = "data-" + order,
929
+ i, j, kid, k, l, x, key;
930
+
931
+ // Filter dupes
932
+ matches = filterDuplicates(matches, children, type);
933
+
934
+ for (i = 0, j = children.length; i < j; i++) {
935
+ kid = children[i];
936
+
937
+ for (k = 0, l = matches.length; k < l; k++) {
938
+ x = matches[k];
939
+
940
+ if (type) {
941
+ // If no value declared, it's the default.
942
+ group = x[order] || "1";
943
+
944
+ if (x.match === kid) {
945
+ x.match.setAttribute(BoxOrdinalAttr, group);
946
+
947
+ groups[group] = groups[group] || [];
948
+ groups[group].push(x);
949
+ }
950
+ } else {
951
+ // If no value declared, it's the default.
952
+ group = x.flex || "0";
953
+
954
+ if (x.match === kid && (!x[group] || (x[group] && parseInt(x[group], 10) <= 1))) {
955
+ totalRatio += parseInt(group, 10);
956
+
957
+ groups[group] = groups[group] || [];
958
+ groups[group].push(x);
959
+ }
960
+ }
961
+ }
962
+
963
+ if (type && !kid.getAttribute(BoxOrdinalAttr)) {
964
+ group = "1";
965
+ kid.setAttribute(BoxOrdinalAttr, group);
966
+
967
+ groups[group] = groups[group] || [];
968
+ groups[group].push({
969
+ match : kid
970
+ });
971
+ }
972
+ }
973
+
974
+ for (key in groups) {
975
+ if (groups.hasOwnProperty(key)) {
976
+ keys.push(key);
977
+ }
978
+ }
979
+
980
+ keys.sort(function (a, b) {
981
+ return b - a;
982
+ });
983
+
984
+ return {
985
+ keys : keys,
986
+ groups : groups,
987
+ total : totalRatio
988
+ };
989
+ }
990
+
991
+ function attachResizeListener(construct, params) {
992
+ if (!RESIZE_LISTENER) {
993
+ var storedWidth, storedHeight,
994
+ currentWidth, currentHeight,
995
+ docBody = doc.body,
996
+ docEl = doc.documentElement,
997
+ resizeTimer,
998
+ innerWidth = "innerWidth", innerHeight = "innerHeight",
999
+ clientWidth = "clientWidth", clientHeight = "clientHeight";
1000
+
1001
+ addEvent("resize", function () {
1002
+ if (resizeTimer) {
1003
+ window.clearTimeout(resizeTimer);
1004
+ }
1005
+
1006
+ resizeTimer = window.setTimeout(function () {
1007
+ currentWidth = win[innerWidth] || docEl[innerWidth] || docEl[clientWidth] || docBody[clientWidth];
1008
+ currentHeight = win[innerHeight] || docEl[innerHeight] || docEl[clientHeight] || docBody[clientHeight];
1009
+
1010
+ if (storedWidth !== currentWidth || storedHeight !== currentHeight) {
1011
+ FLX.updateInstance(NULL, NULL);
1012
+
1013
+ storedWidth = currentWidth;
1014
+ storedHeight = currentHeight;
1015
+ }
1016
+ }, 250);
1017
+ });
1018
+
1019
+ RESIZE_LISTENER = TRUE;
1020
+ }
1021
+ }
1022
+
1023
+ function cleanPositioningProperties (children) {
1024
+ var i, j, kid, w, h;
1025
+
1026
+ for (i = 0, j = children.length; i < j; i++) {
1027
+ kid = children[i];
1028
+
1029
+ w = kid.style.width;
1030
+ h = kid.style.height;
1031
+
1032
+ kid.style.cssText = EMPTY_STRING;
1033
+
1034
+ kid.style.width = w;
1035
+ kid.style.height = h;
1036
+ }
1037
+ }
1038
+
1039
+ function sanitizeChildren (target, nodes) {
1040
+ var children = [], node, i, j;
1041
+
1042
+ for (i = 0, j = nodes.length; i < j; i++) {
1043
+ node = nodes[i];
1044
+
1045
+ if (node) {
1046
+ switch (node.nodeName.toLowerCase()) {
1047
+ case "script" :
1048
+ case "style" :
1049
+ case "link" :
1050
+ break;
1051
+
1052
+ default :
1053
+ if (node.nodeType === 1) {
1054
+ children.push(node);
1055
+ } else if ((node.nodeType === 3) && (node.isElementContentWhitespace || (ONLY_WHITESPACE).test(node.data))) {
1056
+ target.removeChild(node);
1057
+ i--;
1058
+ }
1059
+ break;
1060
+ }
1061
+ }
1062
+ }
1063
+
1064
+ return children;
1065
+ }
1066
+
1067
+ function parentFlex (target) {
1068
+ var totalFlex = 0,
1069
+ parent = target.parentNode,
1070
+ obj,
1071
+ matrix,
1072
+ isNested;
1073
+
1074
+ while (parent.FLX_DOM_ID) {
1075
+ if (FLEX_BOXES[parent.FLX_DOM_ID]) {
1076
+ obj = FLEX_BOXES[parent.FLX_DOM_ID];
1077
+ matrix = createMatchMatrix(obj.children, sanitizeChildren(parent, parent.childNodes), NULL);
1078
+ totalFlex += matrix.total;
1079
+ isNested = TRUE;
1080
+ }
1081
+ parent = parent.parentNode;
1082
+ }
1083
+
1084
+ return {
1085
+ nested : isNested,
1086
+ flex : totalFlex
1087
+ };
1088
+ }
1089
+
1090
+ function dimensionValues (target, prop) {
1091
+ var parent = target.parentNode,
1092
+ obj, dimension, i, j, rule;
1093
+
1094
+ if (parent.FLX_DOM_ID) {
1095
+ obj = FLEX_BOXES[parent.FLX_DOM_ID];
1096
+
1097
+ for (i = 0, j = obj.properties.length; i < j; i++) {
1098
+ rule = obj.properties[i];
1099
+
1100
+ if ((new RegExp(prop)).test(rule.property)) {
1101
+ dimension = TRUE;
1102
+ return FALSE;
1103
+ }
1104
+ }
1105
+ }
1106
+
1107
+ return dimension;
1108
+ }
1109
+
1110
+ function updateChildValues (params) {
1111
+ var i, j, x;
1112
+
1113
+ if (params.flexMatrix) {
1114
+ for (i = 0, j = params.children.length; i < j; i++) {
1115
+ x = params.children[i];
1116
+ x.flex = params.flexMatrix[i];
1117
+ }
1118
+ }
1119
+
1120
+ if (params.ordinalMatrix) {
1121
+ for (i = 0, j = params.children.length; i < j; i++) {
1122
+ x = params.children[i];
1123
+ x["ordinal-group"] = params.ordinalMatrix[i];
1124
+ }
1125
+ }
1126
+
1127
+ return params;
1128
+ }
1129
+
1130
+ function ensureStructuralIntegrity (params, instance) {
1131
+ var target = params.target;
1132
+
1133
+ if (!target.FLX_DOM_ID) {
1134
+ target.FLX_DOM_ID = target.FLX_DOM_ID || (++FLX_DOM_ID);
1135
+ }
1136
+
1137
+ if (!params.nodes) {
1138
+ params.nodes = sanitizeChildren(target, target.childNodes);
1139
+ }
1140
+
1141
+ if (!params.selector) {
1142
+ params.selector = buildSelector(target);
1143
+ target.setAttribute(FLX_PARENT_ATTR, TRUE);
1144
+ }
1145
+
1146
+ if (!params.properties) {
1147
+ params.properties = [];
1148
+ }
1149
+
1150
+ if (!params.children) {
1151
+ params.children = matchFlexChildren(target, LIBRARY, sanitizeChildren(target, target.childNodes));
1152
+ }
1153
+
1154
+ if (!params.nested) {
1155
+ params.nested = params.selector + " [" + FLX_PARENT_ATTR + "]";
1156
+ }
1157
+
1158
+ params.target = target;
1159
+ params._instance = instance;
1160
+
1161
+ return params;
1162
+ }
1163
+
1164
+ selectivizrEngine = (function () {
1165
+ var RE_COMMENT = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*?/g,
1166
+ RE_IMPORT = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))\s*([^;]*);/g,
1167
+ RE_ASSET_URL = /(behavior\s*?:\s*)?\burl\(\s*(["']?)(?!data:)([^"')]+)\2\s*\)/g,
1168
+ RE_SELECTOR_GROUP = /((?:^|(?:\s*\})+)(?:\s*@media[^\{]+\{)?)\s*([^\{]*?[\[:][^{]+)/g,
1169
+
1170
+ // Whitespace normalization regexp's
1171
+ RE_TIDY_TRAILING_WHITESPACE = /([(\[+~])\s+/g,
1172
+ RE_TIDY_LEADING_WHITESPACE = /\s+([)\]+~])/g,
1173
+ RE_TIDY_CONSECUTIVE_WHITESPACE = /\s+/g,
1174
+ RE_TIDY_TRIM_WHITESPACE = /^\s*((?:[\S\s]*\S)?)\s*$/;
1175
+
1176
+ // --[ trim() ]---------------------------------------------------------
1177
+ // removes leading, trailing whitespace from a string
1178
+ function trim(text) {
1179
+ return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING);
1180
+ }
1181
+
1182
+ // --[ normalizeWhitespace() ]------------------------------------------
1183
+ // removes leading, trailing and consecutive whitespace from a string
1184
+ function normalizeWhitespace(text) {
1185
+ return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING);
1186
+ }
1187
+
1188
+ // --[ normalizeSelectorWhitespace() ]----------------------------------
1189
+ // tidys whitespace around selector brackets and combinators
1190
+ function normalizeSelectorWhitespace(selectorText) {
1191
+ return normalizeWhitespace(selectorText.replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING).replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING));
1192
+ }
1193
+
1194
+ // --[ patchStyleSheet() ]----------------------------------------------
1195
+ // Scans the passed cssText for selectors that require emulation and
1196
+ // creates one or more patches for each matched selector.
1197
+ function patchStyleSheet(cssText) {
1198
+ return cssText.replace(RE_SELECTOR_GROUP, function (m, prefix, selectorText) {
1199
+ var selectorGroups, selector,
1200
+ i, j, group;
1201
+
1202
+ selectorGroups = selectorText.split(",");
1203
+
1204
+ for (i = 0, j = selectorGroups.length; i < j; i++) {
1205
+ group = selectorGroups[i];
1206
+ selector = normalizeSelectorWhitespace(group) + SPACE_STRING;
1207
+ }
1208
+
1209
+ return prefix + selectorGroups.join(",");
1210
+ });
1211
+ }
1212
+
1213
+ // --[ getXHRObject() ]-------------------------------------------------
1214
+ function getXHRObject() {
1215
+ if (win.XMLHttpRequest) {
1216
+ return new win.XMLHttpRequest();
1217
+ }
1218
+
1219
+ try {
1220
+ return new win.ActiveXObject("Microsoft.XMLHTTP");
1221
+ } catch (e) {
1222
+ return NULL;
1223
+ }
1224
+ }
1225
+
1226
+ function parseInlineStyles ( text ) {
1227
+ var reg = /<style[^<>]*>([^<>]*)<\/style[\s]?>/img,
1228
+ match = reg.exec(text),
1229
+ stylesheets = [],
1230
+ rawCSSText;
1231
+
1232
+ while (match) {
1233
+ rawCSSText = match[1];
1234
+
1235
+ if (rawCSSText) {
1236
+ stylesheets.push(rawCSSText);
1237
+ }
1238
+
1239
+ match = reg.exec(text);
1240
+ }
1241
+
1242
+ return stylesheets.join("\n\n");
1243
+ }
1244
+
1245
+ // --[ loadStyleSheet() ]-----------------------------------------------
1246
+ function loadStyleSheet(url) {
1247
+ var xhr = getXHRObject(),
1248
+ responseText;
1249
+
1250
+ xhr.open("GET", url, FALSE);
1251
+ xhr.send();
1252
+
1253
+ responseText = (xhr.status === 200) ? xhr.responseText : EMPTY_STRING;
1254
+
1255
+ if (url === window.location.href) {
1256
+ responseText = parseInlineStyles(responseText);
1257
+ }
1258
+
1259
+ return responseText;
1260
+ }
1261
+
1262
+ // --[ resolveUrl() ]---------------------------------------------------
1263
+ // Converts a URL fragment to a fully qualified URL using the specified
1264
+ // context URL. Returns null if same-origin policy is broken
1265
+ function resolveUrl(url, contextUrl) {
1266
+
1267
+ // IE9 returns a false positive sometimes(?)
1268
+ if (!url) {
1269
+ return;
1270
+ }
1271
+
1272
+ function getProtocolAndHost(url) {
1273
+ return url.substring(0, url.indexOf("/", 8));
1274
+ }
1275
+
1276
+ // absolute path
1277
+ if (PROTOCOL.test(url)) {
1278
+ return getProtocolAndHost(contextUrl) === getProtocolAndHost(url) ? url : NULL;
1279
+ }
1280
+
1281
+ // root-relative path
1282
+ if (url.charAt(0) === "/") {
1283
+ return getProtocolAndHost(contextUrl) + url;
1284
+ }
1285
+
1286
+ // relative path
1287
+ var contextUrlPath = contextUrl.split("?")[0]; // ignore query string in the contextUrl
1288
+ if (url.charAt(0) !== "?" && contextUrlPath.charAt(contextUrlPath.length - 1) !== "/") {
1289
+ contextUrlPath = contextUrlPath.substring(0, contextUrlPath.lastIndexOf("/") + 1);
1290
+ }
1291
+
1292
+ return contextUrlPath + url;
1293
+ }
1294
+
1295
+ // --[ parseStyleSheet() ]----------------------------------------------
1296
+ // Downloads the stylesheet specified by the URL, removes it's comments
1297
+ // and recursivly replaces @import rules with their contents, ultimately
1298
+ // returning the full cssText.
1299
+ function parseStyleSheet( url ) {
1300
+ if (url) {
1301
+ return loadStyleSheet(url).replace(RE_COMMENT, EMPTY_STRING).
1302
+ replace(RE_IMPORT, function( match, quoteChar, importUrl, quoteChar2, importUrl2, media ) {
1303
+ var cssText = parseStyleSheet(resolveUrl(importUrl || importUrl2, url));
1304
+ return (media) ? "@media " + media + " {" + cssText + "}" : cssText;
1305
+ }).
1306
+ replace(RE_ASSET_URL, function( match, isBehavior, quoteChar, assetUrl ) {
1307
+ quoteChar = quoteChar || EMPTY_STRING;
1308
+ return isBehavior ? match : " url(" + quoteChar + resolveUrl(assetUrl, url, true) + quoteChar + ") ";
1309
+ });
1310
+ }
1311
+ return EMPTY_STRING;
1312
+ }
1313
+
1314
+ // --[ init() ]---------------------------------------------------------
1315
+ return function () {
1316
+ // honour the <base> tag
1317
+ var url, stylesheets = [], stylesheet, i, j,
1318
+ baseTags = doc.getElementsByTagName("BASE"),
1319
+ baseUrl = (baseTags.length > 0) ? baseTags[0].href : doc.location.href,
1320
+ externalStyles = doc.styleSheets,
1321
+ cssText, tree, flexers;
1322
+
1323
+ for (i = 0, j = externalStyles.length; i < j; i++) {
1324
+ stylesheet = externalStyles[i];
1325
+
1326
+ if (stylesheet != NULL) {
1327
+ stylesheets.push(stylesheet);
1328
+ }
1329
+ }
1330
+
1331
+ // Add self to test for inline styles
1332
+ stylesheets.push(window.location);
1333
+
1334
+ for (i = 0, j = stylesheets.length; i < j; i++) {
1335
+ stylesheet = stylesheets[i];
1336
+
1337
+ if (stylesheet) {
1338
+ url = resolveUrl(stylesheet.href, baseUrl);
1339
+
1340
+ if (url) {
1341
+ cssText = patchStyleSheet(parseStyleSheet(url));
1342
+ }
1343
+
1344
+ if (cssText) {
1345
+ tree = buildSelectorTree(cssText);
1346
+ flexers = findFlexboxElements(tree);
1347
+ }
1348
+ }
1349
+ }
1350
+
1351
+ buildFlexieCall(flexers);
1352
+ };
1353
+ }());
1354
+
1355
+ // Flexie box constructor
1356
+ FLX.box = function (params) {
1357
+ return this.renderModel(params);
1358
+ };
1359
+
1360
+ FLX.box.prototype = {
1361
+ properties : {
1362
+ boxModel : function (target, children, params) {
1363
+ var selectors, stylesheet, paddingFix, generatedRules,
1364
+ i, j, selector;
1365
+
1366
+ target.style.display = "block";
1367
+
1368
+ if (BROWSER.IE === 8) {
1369
+ target.style.overflow = "hidden";
1370
+ }
1371
+
1372
+ // We'll be using floats, so the easiest way to retain layout
1373
+ // is the dreaded clear fix:
1374
+ if (!params.cleared) {
1375
+ selectors = params.selector.split(/\s?,\s?/);
1376
+ stylesheet = doc.styleSheets;
1377
+ stylesheet = stylesheet[stylesheet.length - 1];
1378
+ paddingFix = "padding-top:" + (getComputedStyle(target, PADDING_TOP, NULL) || "0.1px;");
1379
+
1380
+ generatedRules = [
1381
+ "content: '.'",
1382
+ "display: block",
1383
+ "height: 0",
1384
+ "overflow: hidden"
1385
+ ].join(";");
1386
+
1387
+ for (i = 0, j = selectors.length; i < j; i++) {
1388
+ selector = selectors[i];
1389
+
1390
+ if (stylesheet.addRule) {
1391
+ if (BROWSER.IE < 8) {
1392
+ target.style.zoom = "1";
1393
+
1394
+ if (BROWSER.IE === 6) {
1395
+ stylesheet.addRule(selector.replace(/\>|\+|\~/g, ""), paddingFix + "zoom:1;", 0);
1396
+ } else if (BROWSER.IE === 7) {
1397
+ stylesheet.addRule(selector, paddingFix + "display:inline-block;", 0);
1398
+ }
1399
+ } else {
1400
+ stylesheet.addRule(selector, paddingFix, 0);
1401
+ stylesheet.addRule(selector + ":before", generatedRules, 0);
1402
+ stylesheet.addRule(selector + ":after", generatedRules + ";clear:both;", 0);
1403
+ }
1404
+ } else if (stylesheet.insertRule) {
1405
+ stylesheet.insertRule(selector + "{" + paddingFix + "}", 0);
1406
+ stylesheet.insertRule(selector + ":after{" + generatedRules + ";clear:both;}", 0);
1407
+ }
1408
+ }
1409
+
1410
+ params.cleared = TRUE;
1411
+ }
1412
+ },
1413
+
1414
+ boxDirection : function (target, children, params) {
1415
+ var nestedSelector, nested,
1416
+ i, j, kid, node;
1417
+
1418
+ if ((params.direction === "reverse" && !params.reversed) || (params.direction === "normal" && params.reversed)) {
1419
+ children = children.reverse();
1420
+
1421
+ for (i = 0, j = children.length; i < j; i++) {
1422
+ kid = children[i];
1423
+ target.appendChild(kid);
1424
+ }
1425
+
1426
+ // box-direction is inheritable.
1427
+ // We need to see if there are any nested flexbox elements
1428
+ nestedSelector = LIBRARY(params.nested);
1429
+
1430
+ for (i = 0, j = nestedSelector.length; i < j; i++) {
1431
+ node = nestedSelector[i];
1432
+
1433
+ nested = FLEX_BOXES[node.FLX_DOM_ID];
1434
+
1435
+ if (nested && nested.direction === INHERIT) {
1436
+ nested.direction = params.direction;
1437
+ }
1438
+ }
1439
+
1440
+ params.reversed = !params.reversed;
1441
+ }
1442
+ },
1443
+
1444
+ boxOrient : function (target, children, params) {
1445
+ var self = this, wide, high,
1446
+ i, j, kid;
1447
+
1448
+ wide = {
1449
+ pos : "marginLeft",
1450
+ opp : "marginRight",
1451
+ dim : "width",
1452
+ out : "offsetWidth",
1453
+ func : clientWidth,
1454
+ pad : [PADDING_LEFT, PADDING_RIGHT, BORDER_LEFT, BORDER_RIGHT]
1455
+ };
1456
+
1457
+ high = {
1458
+ pos : "marginTop",
1459
+ opp : "marginBottom",
1460
+ dim : "height",
1461
+ out : "offsetHeight",
1462
+ func : clientHeight,
1463
+ pad : [PADDING_TOP, PADDING_BOTTOM, BORDER_TOP, BORDER_BOTTOM]
1464
+ };
1465
+
1466
+ if (!SUPPORT) {
1467
+ for (i = 0, j = children.length; i < j; i++) {
1468
+ kid = children[i];
1469
+
1470
+ kid.style[(BROWSER.IE >= 9) ? "cssFloat" : "styleFloat"] = LEFT;
1471
+
1472
+ if (params.orient === VERTICAL || params.orient === BLOCK_AXIS) {
1473
+ kid.style.clear = LEFT;
1474
+ }
1475
+
1476
+ if (BROWSER.IE === 6) {
1477
+ kid.style.display = "inline";
1478
+ }
1479
+ }
1480
+ }
1481
+
1482
+ switch (params.orient) {
1483
+ case VERTICAL :
1484
+ case BLOCK_AXIS:
1485
+ self.props = high;
1486
+ self.anti = wide;
1487
+ break;
1488
+
1489
+ default :
1490
+ self.props = wide;
1491
+ self.anti = high;
1492
+ break;
1493
+ }
1494
+ },
1495
+
1496
+ boxOrdinalGroup : function (target, children, params) {
1497
+ var organizeChildren,
1498
+ matrix;
1499
+
1500
+ if (!children.length) {
1501
+ return;
1502
+ }
1503
+
1504
+ organizeChildren = function (matrix) {
1505
+ var keys = matrix.keys,
1506
+ iterator = params.reversed ? keys : keys.reverse(),
1507
+ i, j, key, k, l, kid;
1508
+
1509
+ for (i = 0, j = iterator.length; i < j; i++) {
1510
+ key = iterator[i];
1511
+
1512
+ for (k = 0, l = children.length; k < l; k++) {
1513
+ kid = children[k];
1514
+
1515
+ if (key === kid.getAttribute("data-ordinal-group")) {
1516
+ target.appendChild(kid);
1517
+ }
1518
+ }
1519
+ }
1520
+ };
1521
+
1522
+ matrix = createMatchMatrix(params.children, children, TRUE);
1523
+
1524
+ if (matrix.keys.length > 1) {
1525
+ organizeChildren(matrix);
1526
+ }
1527
+ },
1528
+
1529
+ boxFlex : function (target, children, params) {
1530
+ var self = this,
1531
+ testForRestrictiveProperties,
1532
+ findTotalWhitespace,
1533
+ distributeRatio,
1534
+ matrix,
1535
+ restrict,
1536
+ whitespace,
1537
+ distro;
1538
+
1539
+ if (!children.length) {
1540
+ return;
1541
+ }
1542
+
1543
+ testForRestrictiveProperties = function (matrix) {
1544
+ var flexers = matrix.groups,
1545
+ keys = matrix.keys,
1546
+ max, i, j, key,
1547
+ k, l, x, m, n, rule;
1548
+
1549
+ for (i = 0, j = keys.length; i < j; i++) {
1550
+ key = keys[i];
1551
+
1552
+ for (k = 0, l = flexers[key].length; k < l; k++) {
1553
+ x = flexers[key][k];
1554
+ max = NULL;
1555
+
1556
+ for (m = 0, n = x.properties.length; m < n; m++) {
1557
+ rule = x.properties[m];
1558
+
1559
+ if ((RESTRICTIVE_PROPERTIES).test(rule.property)) {
1560
+ max = parseFloat(rule.value);
1561
+ }
1562
+ }
1563
+
1564
+ if (!max || x.match[self.props.out] > max) {
1565
+ appendPixelValue(x.match, self.props.pos, NULL);
1566
+ }
1567
+
1568
+ }
1569
+ }
1570
+ };
1571
+
1572
+ findTotalWhitespace = function (matrix) {
1573
+ var groupDimension = 0,
1574
+ whitespace,
1575
+ ration,
1576
+ i, j, kid,
1577
+ k, l, pad;
1578
+
1579
+ for (i = 0, j = children.length; i < j; i++) {
1580
+ kid = children[i];
1581
+
1582
+ groupDimension += getComputedStyle(kid, self.props.dim, TRUE);
1583
+
1584
+ for (k = 0, l = self.props.pad.length; k < l; k++) {
1585
+ pad = self.props.pad[k];
1586
+
1587
+ groupDimension += getComputedStyle(kid, pad, TRUE);
1588
+ }
1589
+
1590
+ groupDimension += getComputedStyle(kid, self.props.pos, TRUE);
1591
+ groupDimension += getComputedStyle(kid, self.props.opp, TRUE);
1592
+ }
1593
+
1594
+ whitespace = target[self.props.out] - groupDimension;
1595
+
1596
+ for (i = 0, j = self.props.pad.length; i < j; i++) {
1597
+ pad = self.props.pad[i];
1598
+ whitespace -= getComputedStyle(target, pad, TRUE);
1599
+ }
1600
+
1601
+ ration = (whitespace / matrix.total);
1602
+
1603
+ return {
1604
+ whitespace : whitespace,
1605
+ ration : ration
1606
+ };
1607
+ };
1608
+
1609
+ distributeRatio = function (matrix, whitespace) {
1610
+ var flexers = matrix.groups,
1611
+ keys = matrix.keys,
1612
+ flex, specificity,
1613
+ ration = whitespace.ration,
1614
+ widthRation, trueDim, newDimension,
1615
+ i, j, key, k, l, x;
1616
+
1617
+ for (i = 0, j = keys.length; i < j; i++) {
1618
+ key = keys[i];
1619
+ widthRation = (ration * key);
1620
+
1621
+ for (k = 0, l = flexers[key].length; k < l; k++) {
1622
+ x = flexers[key][k];
1623
+
1624
+ if (x.match) {
1625
+ flex = x.match.getAttribute("data-flex");
1626
+ specificity = x.match.getAttribute("data-specificity");
1627
+
1628
+ if (!flex || (specificity <= x.flexSpecificity)) {
1629
+ x.match.setAttribute("data-flex", key);
1630
+ x.match.setAttribute("data-specificity", x.flexSpecificity);
1631
+
1632
+ trueDim = getComputedStyle(x.match, self.props.dim, TRUE);
1633
+ newDimension = Math.max(0, (trueDim + widthRation));
1634
+ appendPixelValue(x.match, self.props.dim, newDimension);
1635
+ }
1636
+ }
1637
+ }
1638
+ }
1639
+ };
1640
+
1641
+ matrix = createMatchMatrix(params.children, children, NULL);
1642
+
1643
+ if (matrix.total) {
1644
+ params.hasFlex = TRUE;
1645
+
1646
+ restrict = testForRestrictiveProperties(matrix);
1647
+ whitespace = findTotalWhitespace(matrix);
1648
+
1649
+ // Distribute the calculated ratios among the children
1650
+ distro = distributeRatio(matrix, whitespace);
1651
+ }
1652
+ },
1653
+
1654
+ boxAlign : function (target, children, params) {
1655
+ var self = this,
1656
+ targetDimension,
1657
+ kidDimension,
1658
+ flexCheck = parentFlex(target),
1659
+ i, j, pad, k, l, kid;
1660
+
1661
+ if (!SUPPORT && !flexCheck.flex && (params.orient === VERTICAL || params.orient === BLOCK_AXIS)) {
1662
+ if (!dimensionValues(target, self.anti.dim)) {
1663
+ appendPixelValue(target, self.anti.dim, NULL);
1664
+ }
1665
+ appendPixelValue(children, self.anti.dim, NULL);
1666
+ }
1667
+
1668
+ // Remove padding / border from target dimension
1669
+ targetDimension = target[self.anti.out];
1670
+
1671
+ for (i = 0, j = self.anti.pad.length; i < j; i++) {
1672
+ pad = self.anti.pad[i];
1673
+ targetDimension -= getComputedStyle(target, pad, TRUE);
1674
+ }
1675
+
1676
+ switch (params.align) {
1677
+ case "start" :
1678
+ break;
1679
+
1680
+ case "end" :
1681
+ for (i = 0, j = children.length; i < j; i++) {
1682
+ kid = children[i];
1683
+
1684
+ kidDimension = targetDimension - kid[self.anti.out];
1685
+ kidDimension -= getComputedStyle(kid, self.anti.opp, TRUE);
1686
+ appendPixelValue(kid, self.anti.pos, kidDimension);
1687
+ }
1688
+ break;
1689
+
1690
+ case "center" :
1691
+ for (i = 0, j = children.length; i < j; i++) {
1692
+ kid = children[i];
1693
+
1694
+ kidDimension = (targetDimension - kid[self.anti.out]) / 2;
1695
+ appendPixelValue(kid, self.anti.pos, kidDimension);
1696
+ }
1697
+ break;
1698
+
1699
+ default :
1700
+ for (i = 0, j = children.length; i < j; i++) {
1701
+ kid = children[i];
1702
+
1703
+ switch (kid.nodeName.toLowerCase()) {
1704
+ case "button" :
1705
+ case "input" :
1706
+ case "select" :
1707
+ break;
1708
+
1709
+ default :
1710
+ var subtract = 0;
1711
+
1712
+ for (k = 0, l = self.anti.pad.length; k < l; k++) {
1713
+ pad = self.anti.pad[k];
1714
+
1715
+ subtract += getComputedStyle(kid, pad, TRUE);
1716
+ subtract += getComputedStyle(target, pad, TRUE);
1717
+ }
1718
+
1719
+ kid.style[self.anti.dim] = "100%";
1720
+ kidDimension = kid[self.anti.out] - subtract;
1721
+ appendPixelValue(kid, self.anti.dim, NULL);
1722
+
1723
+ kidDimension = targetDimension;
1724
+ kidDimension -= getComputedStyle(kid, self.anti.pos, TRUE);
1725
+
1726
+ for (k = 0, l = self.anti.pad.length; k < l; k++) {
1727
+ pad = self.anti.pad[k];
1728
+
1729
+ kidDimension -= getComputedStyle(kid, pad, TRUE);
1730
+ }
1731
+
1732
+ kidDimension -= getComputedStyle(kid, self.anti.opp, TRUE);
1733
+ kidDimension = Math.max(0, kidDimension);
1734
+
1735
+ appendPixelValue(kid, self.anti.dim, kidDimension);
1736
+ break;
1737
+ }
1738
+ }
1739
+ break;
1740
+ }
1741
+ },
1742
+
1743
+ boxPack : function (target, children, params) {
1744
+ var self = this,
1745
+ groupDimension = 0,
1746
+ firstComputedMargin = 0,
1747
+ targetPadding = 0,
1748
+ totalDimension,
1749
+ fractionedDimension,
1750
+ currentDimension,
1751
+ remainder,
1752
+ length = children.length - 1,
1753
+ kid, i, j, value, pad;
1754
+
1755
+ for (i = 0, j = children.length; i < j; i++) {
1756
+ kid = children[i];
1757
+
1758
+ groupDimension += kid[self.props.out];
1759
+ groupDimension += getComputedStyle(kid, self.props.pos, TRUE);
1760
+ groupDimension += getComputedStyle(kid, self.props.opp, TRUE);
1761
+ }
1762
+
1763
+ firstComputedMargin = getComputedStyle(children[0], self.props.pos, TRUE);
1764
+ totalDimension = target[self.props.out] - groupDimension;
1765
+
1766
+ // Remove padding / border from target dimension
1767
+ for (i = 0, j = self.props.pad.length; i < j; i++) {
1768
+ pad = self.props.pad[i];
1769
+ totalDimension -= getComputedStyle(target, pad, TRUE);
1770
+ }
1771
+
1772
+ // If totalDimension is less than 0, we have a problem...
1773
+ if (totalDimension < 0) {
1774
+ totalDimension = Math.max(0, totalDimension);
1775
+ }
1776
+
1777
+ switch (params.pack) {
1778
+ case "end" :
1779
+ appendPixelValue(children[0], self.props.pos, targetPadding + firstComputedMargin + totalDimension);
1780
+ break;
1781
+
1782
+ case "center" :
1783
+ if (targetPadding) {
1784
+ targetPadding /= 2;
1785
+ }
1786
+
1787
+ appendPixelValue(children[0], self.props.pos, targetPadding + firstComputedMargin + Math.floor(totalDimension / 2));
1788
+ break;
1789
+
1790
+ case "justify" :
1791
+ fractionedDimension = Math.floor((targetPadding + totalDimension) / length);
1792
+ remainder = (fractionedDimension * length) - totalDimension;
1793
+
1794
+ i = children.length - 1;
1795
+
1796
+ while (i) {
1797
+ kid = children[i];
1798
+ currentDimension = fractionedDimension;
1799
+
1800
+ if (remainder) {
1801
+ currentDimension++;
1802
+ remainder++;
1803
+ }
1804
+
1805
+ value = getComputedStyle(kid, self.props.pos, TRUE) + currentDimension;
1806
+ appendPixelValue(kid, self.props.pos, value);
1807
+
1808
+ i--;
1809
+ }
1810
+
1811
+ break;
1812
+ }
1813
+
1814
+ target.style.overflow = "";
1815
+ }
1816
+ },
1817
+
1818
+ setup : function (target, children, params) {
1819
+ var self = this, matrix, flexCheck,
1820
+ key, func;
1821
+
1822
+ if (!target || !children || !params) {
1823
+ return;
1824
+ }
1825
+
1826
+ if (SUPPORT && SUPPORT.partialSupport) {
1827
+ matrix = createMatchMatrix(params.children, children, NULL);
1828
+ flexCheck = parentFlex(target);
1829
+ children = sanitizeChildren(target, target.childNodes);
1830
+
1831
+ self.properties.boxOrient.call(self, target, children, params);
1832
+
1833
+ if (!matrix.total || !LIBRARY(params.nested).length) {
1834
+ if ((params.align === "stretch") && !SUPPORT.boxAlignStretch && (!flexCheck.nested || !flexCheck.flex)) {
1835
+ self.properties.boxAlign.call(self, target, children, params);
1836
+ }
1837
+
1838
+ if ((params.pack === "justify") && !SUPPORT.boxPackJustify && !matrix.total) {
1839
+ self.properties.boxPack.call(self, target, children, params);
1840
+ }
1841
+ }
1842
+ } else if (!SUPPORT) {
1843
+ for (key in self.properties) {
1844
+ if (self.properties.hasOwnProperty(key)) {
1845
+ func = self.properties[key];
1846
+ func.call(self, target, sanitizeChildren(target, target.childNodes), params);
1847
+ }
1848
+ }
1849
+ }
1850
+ },
1851
+
1852
+ trackDOM : function (params) {
1853
+ attachResizeListener(this, params);
1854
+ },
1855
+
1856
+ updateModel : function (params) {
1857
+ var self = this,
1858
+ target = params.target,
1859
+ children = params.nodes;
1860
+
1861
+ // Null properties
1862
+ cleanPositioningProperties(children);
1863
+
1864
+ if (params.flexMatrix || params.ordinalMatrix) {
1865
+ params = updateChildValues(params);
1866
+ }
1867
+
1868
+ self.setup(target, children, params);
1869
+ self.bubbleUp(target, params);
1870
+ },
1871
+
1872
+ renderModel : function (params) {
1873
+ var self = this,
1874
+ target = params.target,
1875
+ nodes = target.childNodes;
1876
+
1877
+ // Sanity check.
1878
+ if (!target.length && !nodes) {
1879
+ return false;
1880
+ }
1881
+
1882
+ params = ensureStructuralIntegrity(params, this);
1883
+
1884
+ // Setup properties
1885
+ self.updateModel(params);
1886
+
1887
+ // Resize / DOM Polling Events
1888
+ // Delay for an instant because IE6 is insane.
1889
+ win.setTimeout(function () {
1890
+ self.trackDOM(params);
1891
+ }, 0);
1892
+
1893
+ return self;
1894
+ },
1895
+
1896
+ bubbleUp : function (target, params) {
1897
+ var self = this, flex,
1898
+ parent = params.target.parentNode;
1899
+
1900
+ while (parent) {
1901
+ flex = FLEX_BOXES[parent.FLX_DOM_ID];
1902
+
1903
+ if (flex && flex.nodes) {
1904
+ cleanPositioningProperties(flex.nodes);
1905
+ self.setup(flex.target, flex.nodes, flex);
1906
+ }
1907
+
1908
+ parent = parent.parentNode;
1909
+ }
1910
+ }
1911
+ };
1912
+
1913
+ FLX.updateInstance = function (target, params) {
1914
+ var box, key;
1915
+
1916
+ if (target) {
1917
+ box = FLEX_BOXES[target.FLX_DOM_ID];
1918
+
1919
+ if (box && box._instance) {
1920
+ box._instance.updateModel(box);
1921
+ } else if (!box) {
1922
+ box = new FLX.box(params);
1923
+ }
1924
+ } else {
1925
+ for (key in FLEX_BOXES) {
1926
+ if (FLEX_BOXES.hasOwnProperty(key)) {
1927
+ box = FLEX_BOXES[key];
1928
+
1929
+ if (box && box._instance) {
1930
+ box._instance.updateModel(box);
1931
+ }
1932
+ }
1933
+ }
1934
+ }
1935
+ };
1936
+
1937
+ FLX.getInstance = function (target) {
1938
+ return FLEX_BOXES[target.FLX_DOM_ID];
1939
+ };
1940
+
1941
+ FLX.destroyInstance = function (target) {
1942
+ var box, destroy, i, j, x, key;
1943
+
1944
+ destroy = function (box) {
1945
+ box.target.FLX_DOM_ID = NULL;
1946
+ box.target.style.cssText = EMPTY_STRING;
1947
+
1948
+ for (i = 0, j = box.children.length; i < j; i++) {
1949
+ x = box.children[i];
1950
+ x.match.style.cssText = EMPTY_STRING;
1951
+ }
1952
+ };
1953
+
1954
+ if (target) {
1955
+ box = FLEX_BOXES[target.FLX_DOM_ID];
1956
+
1957
+ if (box) {
1958
+ destroy(box);
1959
+ }
1960
+ } else {
1961
+ for (key in FLEX_BOXES) {
1962
+ if (FLEX_BOXES.hasOwnProperty(key)) {
1963
+ destroy(FLEX_BOXES[key]);
1964
+ }
1965
+ }
1966
+
1967
+ FLEX_BOXES = [];
1968
+ }
1969
+ };
1970
+
1971
+ FLX.flexboxSupport = function () {
1972
+ var partialSupportGrid = {},
1973
+ height = 100,
1974
+ childHeight,
1975
+ dummy = doc.createElement("flxbox"),
1976
+ child = '<b style="margin: 0; padding: 0; display:block; width: 10px; height:' + (height / 2) + 'px"></b>',
1977
+ tests, result, key, value;
1978
+
1979
+ dummy.style.width = dummy.style.height = height + "px";
1980
+ dummy.innerHTML = (child + child + child);
1981
+
1982
+ appendProperty(dummy, "display", "box", NULL);
1983
+ appendProperty(dummy, "box-align", "stretch", TRUE);
1984
+ appendProperty(dummy, "box-pack", "justify", TRUE);
1985
+
1986
+ doc.body.appendChild(dummy);
1987
+ childHeight = dummy.firstChild.offsetHeight;
1988
+
1989
+ tests = {
1990
+ boxAlignStretch : function () {
1991
+ return (childHeight === 100);
1992
+ },
1993
+
1994
+ boxPackJustify : function () {
1995
+ var totalOffset = 0,
1996
+ i, j;
1997
+
1998
+ for (i = 0, j = dummy.childNodes.length; i < j; i++) {
1999
+ totalOffset += dummy.childNodes[i].offsetLeft;
2000
+ }
2001
+
2002
+ return (totalOffset === 135);
2003
+ }
2004
+ };
2005
+
2006
+ for (key in tests) {
2007
+ if (tests.hasOwnProperty(key)) {
2008
+ value = tests[key];
2009
+
2010
+ result = value();
2011
+
2012
+ if (!result) {
2013
+ partialSupportGrid.partialSupport = TRUE;
2014
+ }
2015
+
2016
+ partialSupportGrid[key] = result;
2017
+ }
2018
+ }
2019
+
2020
+ doc.body.removeChild(dummy);
2021
+ return ~ (dummy.style.display).indexOf("box") ? partialSupportGrid : FALSE;
2022
+ };
2023
+
2024
+ FLX.init = function () {
2025
+ FLX.flexboxSupported = SUPPORT = FLX.flexboxSupport();
2026
+
2027
+ if ((!SUPPORT || SUPPORT.partialSupport) && LIBRARY) {
2028
+ selectivizrEngine();
2029
+ }
2030
+ };
2031
+
2032
+ // Flexie Version
2033
+ FLX.version = "1.0.3";
2034
+
2035
+ // Load when the DOM is ready
2036
+ attachLoadMethod(FLX.init);
2037
+
2038
+ return FLX;
2039
+ }(this, document));