25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3 년 전
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. /*!
  2. Holder - 2.3.2 - client side image placeholders
  3. (c) 2012-2014 Ivan Malopinsky / http://imsky.co
  4. Provided under the MIT License.
  5. Commercial use requires attribution.
  6. */
  7. var Holder = Holder || {};
  8. (function (app, win) {
  9. var system_config = {
  10. use_svg: false,
  11. use_canvas: false,
  12. use_fallback: false
  13. };
  14. var instance_config = {};
  15. var preempted = false;
  16. canvas = document.createElement('canvas');
  17. var dpr = 1, bsr = 1;
  18. var resizable_images = [];
  19. if (!canvas.getContext) {
  20. system_config.use_fallback = true;
  21. } else {
  22. if (canvas.toDataURL("image/png")
  23. .indexOf("data:image/png") < 0) {
  24. //Android doesn't support data URI
  25. system_config.use_fallback = true;
  26. } else {
  27. var ctx = canvas.getContext("2d");
  28. }
  29. }
  30. if(!!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect){
  31. system_config.use_svg = true;
  32. system_config.use_canvas = false;
  33. }
  34. if(!system_config.use_fallback){
  35. dpr = window.devicePixelRatio || 1,
  36. bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
  37. }
  38. var ratio = dpr / bsr;
  39. var settings = {
  40. domain: "holder.js",
  41. images: "img",
  42. bgnodes: ".holderjs",
  43. themes: {
  44. "gray": {
  45. background: "#eee",
  46. foreground: "#aaa",
  47. size: 12
  48. },
  49. "social": {
  50. background: "#3a5a97",
  51. foreground: "#fff",
  52. size: 12
  53. },
  54. "industrial": {
  55. background: "#434A52",
  56. foreground: "#C2F200",
  57. size: 12
  58. },
  59. "sky": {
  60. background: "#0D8FDB",
  61. foreground: "#fff",
  62. size: 12
  63. },
  64. "vine": {
  65. background: "#39DBAC",
  66. foreground: "#1E292C",
  67. size: 12
  68. },
  69. "lava": {
  70. background: "#F8591A",
  71. foreground: "#1C2846",
  72. size: 12
  73. }
  74. },
  75. stylesheet: ""
  76. };
  77. app.flags = {
  78. dimensions: {
  79. regex: /^(\d+)x(\d+)$/,
  80. output: function (val) {
  81. var exec = this.regex.exec(val);
  82. return {
  83. width: +exec[1],
  84. height: +exec[2]
  85. }
  86. }
  87. },
  88. fluid: {
  89. regex: /^([0-9%]+)x([0-9%]+)$/,
  90. output: function (val) {
  91. var exec = this.regex.exec(val);
  92. return {
  93. width: exec[1],
  94. height: exec[2]
  95. }
  96. }
  97. },
  98. colors: {
  99. regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
  100. output: function (val) {
  101. var exec = this.regex.exec(val);
  102. return {
  103. size: settings.themes.gray.size,
  104. foreground: "#" + exec[2],
  105. background: "#" + exec[1]
  106. }
  107. }
  108. },
  109. text: {
  110. regex: /text\:(.*)/,
  111. output: function (val) {
  112. return this.regex.exec(val)[1];
  113. }
  114. },
  115. font: {
  116. regex: /font\:(.*)/,
  117. output: function (val) {
  118. return this.regex.exec(val)[1];
  119. }
  120. },
  121. auto: {
  122. regex: /^auto$/
  123. },
  124. textmode: {
  125. regex: /textmode\:(.*)/,
  126. output: function(val){
  127. return this.regex.exec(val)[1];
  128. }
  129. }
  130. }
  131. function text_size(width, height, template) {
  132. height = parseInt(height, 10);
  133. width = parseInt(width, 10);
  134. var bigSide = Math.max(height, width)
  135. var smallSide = Math.min(height, width)
  136. var scale = 1 / 12;
  137. var newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale);
  138. return {
  139. height: Math.round(Math.max(template.size, newHeight))
  140. }
  141. }
  142. var svg_el = (function(){
  143. //Prevent IE <9 from initializing SVG renderer
  144. if(!window.XMLSerializer) return;
  145. var serializer = new XMLSerializer();
  146. var svg_ns = "http://www.w3.org/2000/svg"
  147. var svg = document.createElementNS(svg_ns, "svg");
  148. //IE throws an exception if this is set and Chrome requires it to be set
  149. if(svg.webkitMatchesSelector){
  150. svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
  151. }
  152. var bg_el = document.createElementNS(svg_ns, "rect")
  153. var text_el = document.createElementNS(svg_ns, "text")
  154. var textnode_el = document.createTextNode(null)
  155. text_el.setAttribute("text-anchor", "middle")
  156. text_el.appendChild(textnode_el)
  157. svg.appendChild(bg_el)
  158. svg.appendChild(text_el)
  159. return function(props){
  160. svg.setAttribute("width",props.width);
  161. svg.setAttribute("height", props.height);
  162. bg_el.setAttribute("width", props.width);
  163. bg_el.setAttribute("height", props.height);
  164. bg_el.setAttribute("fill", props.template.background);
  165. text_el.setAttribute("x", props.width/2)
  166. text_el.setAttribute("y", props.height/2)
  167. textnode_el.nodeValue=props.text
  168. text_el.setAttribute("style", css_properties({
  169. "fill": props.template.foreground,
  170. "font-weight": "bold",
  171. "font-size": props.text_height+"px",
  172. "font-family":props.font,
  173. "dominant-baseline":"central"
  174. }))
  175. return serializer.serializeToString(svg)
  176. }
  177. })()
  178. function css_properties(props){
  179. var ret = [];
  180. for(p in props){
  181. if(props.hasOwnProperty(p)){
  182. ret.push(p+":"+props[p])
  183. }
  184. }
  185. return ret.join(";")
  186. }
  187. function draw_canvas(args) {
  188. var ctx = args.ctx,
  189. dimensions = args.dimensions,
  190. template = args.template,
  191. ratio = args.ratio,
  192. holder = args.holder,
  193. literal = holder.textmode == "literal",
  194. exact = holder.textmode == "exact";
  195. var ts = text_size(dimensions.width, dimensions.height, template);
  196. var text_height = ts.height;
  197. var width = dimensions.width * ratio,
  198. height = dimensions.height * ratio;
  199. var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
  200. canvas.width = width;
  201. canvas.height = height;
  202. ctx.textAlign = "center";
  203. ctx.textBaseline = "middle";
  204. ctx.fillStyle = template.background;
  205. ctx.fillRect(0, 0, width, height);
  206. ctx.fillStyle = template.foreground;
  207. ctx.font = "bold " + text_height + "px " + font;
  208. var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
  209. if (literal) {
  210. var dimensions = holder.dimensions;
  211. text = dimensions.width + "x" + dimensions.height;
  212. }
  213. else if(exact && holder.exact_dimensions){
  214. var dimensions = holder.exact_dimensions;
  215. text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
  216. }
  217. var text_width = ctx.measureText(text).width;
  218. if (text_width / width >= 0.75) {
  219. text_height = Math.floor(text_height * 0.75 * (width / text_width));
  220. }
  221. //Resetting font size if necessary
  222. ctx.font = "bold " + (text_height * ratio) + "px " + font;
  223. ctx.fillText(text, (width / 2), (height / 2), width);
  224. return canvas.toDataURL("image/png");
  225. }
  226. function draw_svg(args){
  227. var dimensions = args.dimensions,
  228. template = args.template,
  229. holder = args.holder,
  230. literal = holder.textmode == "literal",
  231. exact = holder.textmode == "exact";
  232. var ts = text_size(dimensions.width, dimensions.height, template);
  233. var text_height = ts.height;
  234. var width = dimensions.width,
  235. height = dimensions.height;
  236. var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
  237. var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
  238. if (literal) {
  239. var dimensions = holder.dimensions;
  240. text = dimensions.width + "x" + dimensions.height;
  241. }
  242. else if(exact && holder.exact_dimensions){
  243. var dimensions = holder.exact_dimensions;
  244. text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
  245. }
  246. var string = svg_el({
  247. text: text,
  248. width:width,
  249. height:height,
  250. text_height:text_height,
  251. font:font,
  252. template:template
  253. })
  254. return "data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(string)));
  255. }
  256. function draw(args) {
  257. if(instance_config.use_canvas && !instance_config.use_svg){
  258. return draw_canvas(args);
  259. }
  260. else{
  261. return draw_svg(args);
  262. }
  263. }
  264. function render(mode, el, holder, src) {
  265. var dimensions = holder.dimensions,
  266. theme = holder.theme,
  267. text = holder.text ? decodeURIComponent(holder.text) : holder.text;
  268. var dimensions_caption = dimensions.width + "x" + dimensions.height;
  269. theme = (text ? extend(theme, {
  270. text: text
  271. }) : theme);
  272. theme = (holder.font ? extend(theme, {
  273. font: holder.font
  274. }) : theme);
  275. el.setAttribute("data-src", src);
  276. holder.theme = theme;
  277. el.holder_data = holder;
  278. if (mode == "image") {
  279. el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
  280. if (instance_config.use_fallback || !holder.auto) {
  281. el.style.width = dimensions.width + "px";
  282. el.style.height = dimensions.height + "px";
  283. }
  284. if (instance_config.use_fallback) {
  285. el.style.backgroundColor = theme.background;
  286. } else {
  287. el.setAttribute("src", draw({ctx: ctx, dimensions: dimensions, template: theme, ratio:ratio, holder: holder}));
  288. if(holder.textmode && holder.textmode == "exact"){
  289. resizable_images.push(el);
  290. resizable_update(el);
  291. }
  292. }
  293. } else if (mode == "background") {
  294. if (!instance_config.use_fallback) {
  295. el.style.backgroundImage = "url(" + draw({ctx:ctx, dimensions: dimensions, template: theme, ratio: ratio, holder: holder}) + ")";
  296. el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px";
  297. }
  298. } else if (mode == "fluid") {
  299. el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
  300. if (dimensions.height.slice(-1) == "%") {
  301. el.style.height = dimensions.height
  302. } else if(holder.auto == null || !holder.auto){
  303. el.style.height = dimensions.height + "px"
  304. }
  305. if (dimensions.width.slice(-1) == "%") {
  306. el.style.width = dimensions.width
  307. } else if(holder.auto == null || !holder.auto){
  308. el.style.width = dimensions.width + "px"
  309. }
  310. if (el.style.display == "inline" || el.style.display === "" || el.style.display == "none") {
  311. el.style.display = "block";
  312. }
  313. set_initial_dimensions(el)
  314. if (instance_config.use_fallback) {
  315. el.style.backgroundColor = theme.background;
  316. } else {
  317. resizable_images.push(el);
  318. resizable_update(el);
  319. }
  320. }
  321. }
  322. function dimension_check(el, callback) {
  323. var dimensions = {
  324. height: el.clientHeight,
  325. width: el.clientWidth
  326. };
  327. if (!dimensions.height && !dimensions.width) {
  328. el.setAttribute("data-holder-invisible", true)
  329. callback.call(this, el)
  330. }
  331. else{
  332. el.removeAttribute("data-holder-invisible")
  333. return dimensions;
  334. }
  335. }
  336. function set_initial_dimensions(el){
  337. if(el.holder_data){
  338. var dimensions = dimension_check(el, app.invisible_error_fn( set_initial_dimensions))
  339. if(dimensions){
  340. var holder = el.holder_data;
  341. holder.initial_dimensions = dimensions;
  342. holder.fluid_data = {
  343. fluid_height: holder.dimensions.height.slice(-1) == "%",
  344. fluid_width: holder.dimensions.width.slice(-1) == "%",
  345. mode: null
  346. }
  347. if(holder.fluid_data.fluid_width && !holder.fluid_data.fluid_height){
  348. holder.fluid_data.mode = "width"
  349. holder.fluid_data.ratio = holder.initial_dimensions.width / parseFloat(holder.dimensions.height)
  350. }
  351. else if(!holder.fluid_data.fluid_width && holder.fluid_data.fluid_height){
  352. holder.fluid_data.mode = "height";
  353. holder.fluid_data.ratio = parseFloat(holder.dimensions.width) / holder.initial_dimensions.height
  354. }
  355. }
  356. }
  357. }
  358. function resizable_update(element) {
  359. var images;
  360. if (element.nodeType == null) {
  361. images = resizable_images;
  362. } else {
  363. images = [element]
  364. }
  365. for (var i in images) {
  366. if (!images.hasOwnProperty(i)) {
  367. continue;
  368. }
  369. var el = images[i]
  370. if (el.holder_data) {
  371. var holder = el.holder_data;
  372. var dimensions = dimension_check(el, app.invisible_error_fn( resizable_update))
  373. if(dimensions){
  374. if(holder.fluid){
  375. if(holder.auto){
  376. switch(holder.fluid_data.mode){
  377. case "width":
  378. dimensions.height = dimensions.width / holder.fluid_data.ratio;
  379. break;
  380. case "height":
  381. dimensions.width = dimensions.height * holder.fluid_data.ratio;
  382. break;
  383. }
  384. }
  385. el.setAttribute("src", draw({
  386. ctx: ctx,
  387. dimensions: dimensions,
  388. template: holder.theme,
  389. ratio: ratio,
  390. holder: holder
  391. }))
  392. }
  393. if(holder.textmode && holder.textmode == "exact"){
  394. holder.exact_dimensions = dimensions;
  395. el.setAttribute("src", draw({
  396. ctx: ctx,
  397. dimensions: holder.dimensions,
  398. template: holder.theme,
  399. ratio: ratio,
  400. holder: holder
  401. }))
  402. }
  403. }
  404. }
  405. }
  406. }
  407. function parse_flags(flags, options) {
  408. var ret = {
  409. theme: extend(settings.themes.gray, {})
  410. };
  411. var render = false;
  412. for (var fl = flags.length, j = 0; j < fl; j++) {
  413. var flag = flags[j];
  414. if (app.flags.dimensions.match(flag)) {
  415. render = true;
  416. ret.dimensions = app.flags.dimensions.output(flag);
  417. } else if (app.flags.fluid.match(flag)) {
  418. render = true;
  419. ret.dimensions = app.flags.fluid.output(flag);
  420. ret.fluid = true;
  421. } else if (app.flags.textmode.match(flag)) {
  422. ret.textmode = app.flags.textmode.output(flag)
  423. } else if (app.flags.colors.match(flag)) {
  424. ret.theme = app.flags.colors.output(flag);
  425. } else if (options.themes[flag]) {
  426. //If a theme is specified, it will override custom colors
  427. if(options.themes.hasOwnProperty(flag)){
  428. ret.theme = extend(options.themes[flag], {});
  429. }
  430. } else if (app.flags.font.match(flag)) {
  431. ret.font = app.flags.font.output(flag);
  432. } else if (app.flags.auto.match(flag)) {
  433. ret.auto = true;
  434. } else if (app.flags.text.match(flag)) {
  435. ret.text = app.flags.text.output(flag);
  436. }
  437. }
  438. return render ? ret : false;
  439. }
  440. for (var flag in app.flags) {
  441. if (!app.flags.hasOwnProperty(flag)) continue;
  442. app.flags[flag].match = function (val) {
  443. return val.match(this.regex)
  444. }
  445. }
  446. app.invisible_error_fn = function(fn){
  447. return function(el){
  448. if(el.hasAttribute("data-holder-invisible")){
  449. throw new Error("Holder: invisible placeholder")
  450. }
  451. }
  452. }
  453. app.add_theme = function (name, theme) {
  454. name != null && theme != null && (settings.themes[name] = theme);
  455. return app;
  456. };
  457. app.add_image = function (src, el) {
  458. var node = selector(el);
  459. if (node.length) {
  460. for (var i = 0, l = node.length; i < l; i++) {
  461. var img = document.createElement("img")
  462. img.setAttribute("data-src", src);
  463. node[i].appendChild(img);
  464. }
  465. }
  466. return app;
  467. };
  468. app.run = function (o) {
  469. instance_config = extend({}, system_config)
  470. preempted = true;
  471. var options = extend(settings, o),
  472. images = [],
  473. imageNodes = [],
  474. bgnodes = [];
  475. if(options.use_canvas != null && options.use_canvas){
  476. instance_config.use_canvas = true;
  477. instance_config.use_svg = false;
  478. }
  479. if (typeof (options.images) == "string") {
  480. imageNodes = selector(options.images);
  481. } else if (window.NodeList && options.images instanceof window.NodeList) {
  482. imageNodes = options.images;
  483. } else if (window.Node && options.images instanceof window.Node) {
  484. imageNodes = [options.images];
  485. } else if(window.HTMLCollection && options.images instanceof window.HTMLCollection){
  486. imageNodes = options.images
  487. }
  488. if (typeof (options.bgnodes) == "string") {
  489. bgnodes = selector(options.bgnodes);
  490. } else if (window.NodeList && options.elements instanceof window.NodeList) {
  491. bgnodes = options.bgnodes;
  492. } else if (window.Node && options.bgnodes instanceof window.Node) {
  493. bgnodes = [options.bgnodes];
  494. }
  495. for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
  496. var holdercss = document.getElementById("holderjs-style");
  497. if (!holdercss) {
  498. holdercss = document.createElement("style");
  499. holdercss.setAttribute("id", "holderjs-style");
  500. holdercss.type = "text/css";
  501. document.getElementsByTagName("head")[0].appendChild(holdercss);
  502. }
  503. if (!options.nocss) {
  504. if (holdercss.styleSheet) {
  505. holdercss.styleSheet.cssText += options.stylesheet;
  506. } else {
  507. if(options.stylesheet.length){
  508. holdercss.appendChild(document.createTextNode(options.stylesheet));
  509. }
  510. }
  511. }
  512. var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
  513. for (var l = bgnodes.length, i = 0; i < l; i++) {
  514. var src = window.getComputedStyle(bgnodes[i], null)
  515. .getPropertyValue("background-image");
  516. var flags = src.match(cssregex);
  517. var bgsrc = bgnodes[i].getAttribute("data-background-src");
  518. if (flags) {
  519. var holder = parse_flags(flags[1].split("/"), options);
  520. if (holder) {
  521. render("background", bgnodes[i], holder, src);
  522. }
  523. } else if (bgsrc != null) {
  524. var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1)
  525. .split("/"), options);
  526. if (holder) {
  527. render("background", bgnodes[i], holder, src);
  528. }
  529. }
  530. }
  531. for (l = images.length, i = 0; i < l; i++) {
  532. var attr_data_src, attr_src;
  533. attr_src = attr_data_src = src = null;
  534. try {
  535. attr_src = images[i].getAttribute("src");
  536. attr_datasrc = images[i].getAttribute("data-src");
  537. } catch (e) {}
  538. if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) {
  539. src = attr_src;
  540. } else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) {
  541. src = attr_datasrc;
  542. }
  543. if (src) {
  544. var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1).split("/"), options);
  545. if (holder) {
  546. if (holder.fluid) {
  547. render("fluid", images[i], holder, src)
  548. } else {
  549. render("image", images[i], holder, src);
  550. }
  551. }
  552. }
  553. }
  554. return app;
  555. };
  556. contentLoaded(win, function () {
  557. if (window.addEventListener) {
  558. window.addEventListener("resize", resizable_update, false);
  559. window.addEventListener("orientationchange", resizable_update, false);
  560. } else {
  561. window.attachEvent("onresize", resizable_update)
  562. }
  563. preempted || app.run({});
  564. if (typeof window.Turbolinks === "object") {
  565. document.addEventListener("page:change", function() { app.run({}) })
  566. }
  567. });
  568. if (typeof define === "function" && define.amd) {
  569. define([], function () {
  570. return app;
  571. });
  572. }
  573. //github.com/davidchambers/Base64.js
  574. (function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
  575. //getElementsByClassName polyfill
  576. document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i<n.length;i++)r.test(n[i].className)&&s.push(n[i])}return s})
  577. //getComputedStyle polyfill
  578. window.getComputedStyle||(window.getComputedStyle=function(e){return this.el=e,this.getPropertyValue=function(t){var n=/(\-([a-z]){1})/g;return t=="float"&&(t="styleFloat"),n.test(t)&&(t=t.replace(n,function(){return arguments[2].toUpperCase()})),e.currentStyle[t]?e.currentStyle[t]:null},this})
  579. //http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications
  580. function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?"addEventListener":"attachEvent",v=i.addEventListener?"removeEventListener":"detachEvent",f=i.addEventListener?"":"on",r=function(e){(e.type!=s||i.readyState==l)&&((e.type=="load"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll("left")}catch(n){setTimeout(o,50);return}r("poll")};if(i.readyState==l)t.call(n,"lazy");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+"DOMContentLoaded",r,u),i[e](f+s,r,u),n[e](f+"load",r,u)}}
  581. //https://gist.github.com/991057 by Jed Schmidt with modifications
  582. function selector(a,b){var a=a.match(/^(\W)?(.*)/),b=b||document,c=b["getElement"+(a[1]?"#"==a[1]?"ById":"sByClassName":"sByTagName")],d=c.call(b,a[2]),e=[];return null!==d&&(e=d.length||0===d.length?d:[d]),e}
  583. //shallow object property extend
  584. function extend(a,b){
  585. var c={};
  586. for(var i in a){
  587. if(a.hasOwnProperty(i)){
  588. c[i]=a[i];
  589. }
  590. }
  591. for(var i in b){
  592. if(b.hasOwnProperty(i)){
  593. c[i]=b[i];
  594. }
  595. }
  596. return c
  597. }
  598. //hasOwnProperty polyfill
  599. if (!Object.prototype.hasOwnProperty)
  600. /*jshint -W001, -W103 */
  601. Object.prototype.hasOwnProperty = function(prop) {
  602. var proto = this.__proto__ || this.constructor.prototype;
  603. return (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]);
  604. }
  605. /*jshint +W001, +W103 */
  606. })(Holder, window);