http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/fonts/font-awesome/fontawesome-webfont.woff ---------------------------------------------------------------------- diff --git a/build/content/fonts/font-awesome/fontawesome-webfont.woff b/build/content/fonts/font-awesome/fontawesome-webfont.woff new file mode 100644 index 0000000..1b92d42 Binary files /dev/null and b/build/content/fonts/font-awesome/fontawesome-webfont.woff differ
http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/fonts/font-awesome/fontawesome-webfont.woff2 ---------------------------------------------------------------------- diff --git a/build/content/fonts/font-awesome/fontawesome-webfont.woff2 b/build/content/fonts/font-awesome/fontawesome-webfont.woff2 new file mode 100644 index 0000000..88095c7 Binary files /dev/null and b/build/content/fonts/font-awesome/fontawesome-webfont.woff2 differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/images/favicon.ico ---------------------------------------------------------------------- diff --git a/build/content/images/favicon.ico b/build/content/images/favicon.ico new file mode 100644 index 0000000..00aa630 Binary files /dev/null and b/build/content/images/favicon.ico differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/img/apache_geode_logo.png ---------------------------------------------------------------------- diff --git a/build/content/img/apache_geode_logo.png b/build/content/img/apache_geode_logo.png new file mode 100644 index 0000000..14b6ac0 Binary files /dev/null and b/build/content/img/apache_geode_logo.png differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/img/apache_geode_logo_white.png ---------------------------------------------------------------------- diff --git a/build/content/img/apache_geode_logo_white.png b/build/content/img/apache_geode_logo_white.png new file mode 100644 index 0000000..2a0cda8 Binary files /dev/null and b/build/content/img/apache_geode_logo_white.png differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/img/apache_geode_logo_white_small.png ---------------------------------------------------------------------- diff --git a/build/content/img/apache_geode_logo_white_small.png b/build/content/img/apache_geode_logo_white_small.png new file mode 100644 index 0000000..bf8aaa0 Binary files /dev/null and b/build/content/img/apache_geode_logo_white_small.png differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/img/asf_logo.png ---------------------------------------------------------------------- diff --git a/build/content/img/asf_logo.png b/build/content/img/asf_logo.png new file mode 100644 index 0000000..8dca813 Binary files /dev/null and b/build/content/img/asf_logo.png differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/img/check_flat/default.png ---------------------------------------------------------------------- diff --git a/build/content/img/check_flat/default.png b/build/content/img/check_flat/default.png new file mode 100755 index 0000000..5a89765 Binary files /dev/null and b/build/content/img/check_flat/default.png differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/img/github.png ---------------------------------------------------------------------- diff --git a/build/content/img/github.png b/build/content/img/github.png new file mode 100644 index 0000000..f19ee0d Binary files /dev/null and b/build/content/img/github.png differ http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/index.html ---------------------------------------------------------------------- diff --git a/build/content/index.html b/build/content/index.html new file mode 100644 index 0000000..5033a4e --- /dev/null +++ b/build/content/index.html @@ -0,0 +1,357 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <!-- Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. --> + <meta charset="utf-8"> + <title>Apache Geode â Performance is key. Consistency is a must.</title> + <meta http-equiv="x-ua-compatible" content="ie=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> + <meta name="keywords" content="Apache Geode, Geode, GemFire, In-memory, IMDB, IMDG, cache"> + <meta name="description" content="Apache Geode is a distributed, in-memory database with strong data consistency, built to support transactional applications with low latency and high concurrency needs." /> + <meta property="og:title" content="Apache Geode" /> + <meta property="og:description" content="Apache Geode is a distributed, in-memory database with strong data consistency, built to support transactional applications with low latency and high concurrency needs." /> + <!-- Loading Typekit --> + <script type="text/javascript" src="//use.typekit.net/ddl7izx.js"></script> + <script type="text/javascript">try{Typekit.load();}catch(e){}</script> + <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> + <!-- Enabling Issue collector --> + <script type="text/javascript" src="https://issues.apache.org/jira/s/bfe7c1e06d911e53fc96873d31176352-T/en_UK-ugtin9/6332/81/1.4.15/_/download/batch/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector/com.atlassian.jira.collector.plugin.jira-issue-collector-plugin:issuecollector.js?locale=en-UK&collectorId=2e0eeb8d"></script> + + <!-- Place this tag right after the last button or just before your close body tag. --> + <script async defer id="github-bjs" src="https://buttons.github.io/buttons.js"></script> + <!-- Loading Bootstrap --> + <link href="/bootstrap/bootstrap.min.css" rel="stylesheet" type='text/css'> + <link href="/css/bootflat.css" rel="stylesheet" type='text/css'> + <link href="/css/geode-site.css" rel="stylesheet" type='text/css'> + <link href="https://fonts.googleapis.com/css?family=Open+Sans:200,400,500,300,600,800,700,400italic,600italic,700italic,800italic,300italic" rel="stylesheet" type="text/css"> + <link href="/css/font-awesome.min.css" rel="stylesheet" type='text/css'> + +<!-- google analytics --> + <script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-63425957-1', 'auto'); + ga('send', 'pageview'); +</script> +<!-- end google analytics --> + + + + <!-- HTML5 shim, for IE6-8 support of HTML5 elements. All other JS at the end of file. --> + <!--[if lt IE 9]> + <script src="js/html5shiv.js"></script> + <script src="js/respond.min.js"></script> + <![endif]--> +</head> +<body> + + <header class="navbar navbar-inverse navbar-fixed-top bf-docs-nav " role="banner"> + <div class="container"> + <div class="navbar-header"> + <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".bf-navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + </div> + <a href="/" class="navbar-brand"> + <img id="home-logo" src="/img/apache_geode_logo_white_small.png" /> + </a> + <nav class="collapse navbar-collapse bf-navbar-collapse" role="navigation"> + <ul class="nav navbar-nav navbar-right"> + <li class=""><a href="/community/"><span class="fa fa-users"></span></a></li> + <li class=""><a href="/docs/"><span class="fa fa-book"></span></a></li> + <li><a href="http://github.com/apache/geode" target="_blank"><span class="fa fa-github-square"></span></a></li> + <li><a href="https://issues.apache.org/jira/browse/GEODE/" target="_blank"><span class="fa fa-bug"></span></a></li> + <li><a href="http://stackoverflow.com/search?q=Apache%20Geode" target="_blank"><span class="fa fa-stack-overflow"></span></a></li> + <li><a href="/community/#mailing-lists"><span class="fa fa-envelope"></span></a></li> + <li><a href="https://twitter.com/apachegeode" target="_blank"><span class="fa fa-twitter"></span></a></li> + <li><a href="https://cwiki.apache.org/confluence/display/geode/" target="_blank"><span class="fa fa-pencil-square-o"></span></a></li> + <li class=""><a href="/releases/"><span class="fa fa-arrow-circle-o-down"></span></a></li> + </ul> + </nav> + </div> + </header> + + +<!-- Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. --> + +<section class="bf-masthead" id="content" role="main"> + <div class="bf-masthead-bg"> + <div class="container"> + <img class="logo-title img-responsive hidden-xs" src="img/apache_geode_logo.png" /> + <div class="text-container"> + <h2 class="tagline"><em>Performance</em> is key. <em>Consistency</em> is a must.</h2> + <p class="description">Providing low latency, high concurrency data management solutions since 2002.<br/> + <br/>Build high-speed, data-intensive applications that elastically meet performance requirements at any scale.<br/> + Take advantage of Apache Geode's unique technology that blends advanced techniques for data replication, partitioning and distributed processing. + + <br/><br/> + Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing.<br/> + </div> + + <div class="btn-wrapper"> + <p><a href="/releases/" class="btn btn-inverse btn-lg">Download Geode</a> </p> + <!-- Place this tag where you want the button to render. --> + <a class="github-button" href="https://github.com/apache/geode" data-icon="octicon-star" data-style="mega" data-count-href="/apache/geode/stargazers" data-count-api="/repos/apache/geode#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star apache/geode on GitHub">Star</a> + <a class="github-button" href="https://github.com/apache/geode/fork" data-icon="octicon-repo-forked" data-style="mega" data-count-href="/apache/geode/network" data-count-api="/repos/apache/geode#forks_count" data-count-aria-label="# forks on GitHub" aria-label="Fork apache/geode on GitHub">Fork</a> + <a class="github-button" href="https://github.com/apache/geode" data-icon="octicon-eye" data-style="mega" data-count-href="/apache/geode/watchers" data-count-api="/repos/apache/geode#subscribers_count" data-count-aria-label="# watchers on GitHub" aria-label="Watch apache/geode on GitHub">Watch</a> + + + </div> + </div> + </div> +</section> + +<section class="bf-features"> + <div class="container"> + <div class="row"> + <div class="col-md-4"> + <div class="bf-icon-wrap"><i style="font-size:65px; vertical-align: -5px;" aria-hidden="true" class="fa fa-sitemap"></i></div> + <h3>Replication and Partitioning</h3> + <p>Data can easily be partitioned (sharded) or replicated between nodes allowing performance to scale as needed. Durability is ensured through redundant in-memory copies and disk-based persistence.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap"><i style="font-size:65px; vertical-align: -5px;" aria-hidden="true" class="fa fa-hdd-o"></i></div> + <h3>Persistence</h3> + <p>Super fast write-ahead-logging (WAL) persistence with a shared-nothing architecture that is optimized for fast parallel recovery of nodes or an entire cluster.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap"><i aria-hidden="true" class="fa fa-rocket"></i></div> + <h3>Performance</h3> + <p>Linear-scaling low latency for transactions, reads, writes and query processing of indexed or unindexed data.</p> + </div> + </div> + <div class="row"> + <div class="col-md-4"> + <div class="bf-icon-wrap" style="font-size:40px; vertical-align: 15px;"><i aria-hidden="true" class="fa fa-fast-forward"></i><i aria-hidden="true" class="fa fa-dashboard"></i></div> + <h3>In-Memory Storage</h3> + <p>Blazing fast in-memory storage optimized for large heaps, with the option of using off-heap storage, compression and features such as disk-overflow, eviction and expiration of data.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap"><span style="font-size:60px" aria-hidden="true" class="fa fa-cogs"></span></div> + <h3>Functions</h3> + <p>Distributed location-aware user functions can be deployed and executed by the same nodes storing relevant sharded data for fast parallel processing. Failed operations can be retried on replicant nodes.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap"><i style="font-size:65px; vertical-align: -5px;" aria-hidden="true" class="fa fa-credit-card"></i></div> + <h3>Transactions</h3> + <p>ACID distributed transactions support efficient and safe coordinated operations on colocated data. Transactions can be initiated or suspended by either a client or a server.</p> + </div> + </div> + <div class="row"> + <div class="col-md-4"> + <div class="bf-icon-wrap"><i style="font-size:65px; vertical-align: -5px;" aria-hidden="true" class="fa fa-table"></i></div> + <h3>OQL and Indexes</h3> + <p>Object Query Language allows distributed query execution on hot and cold data, with SQL-like capabilities, including joins.<br/> + Multiple kinds of indexes can be defined and consistently maintained across the cluster.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap"><i style="font-size:65px; vertical-align: -5px;" aria-hidden="true" class="fa fa-bolt"></i></div> + <h3>Events</h3> + <p>Clients can be notified about server-side data events, and servers can react synchronously or asynchronously with guaranteed delivery of ordered events.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap"><i style="font-size:65px; vertical-align: -5px;" aria-hidden="true" class="fa fa-cloud"></i></div> + <h3>Clustering</h3> + <p>Highly scalable, robust advanced clustering technology with failure detection, dynamic scaling, and network-partition detection algorithms.</p> + </div> + </div> + <div class="row"> + <div class="col-md-4"> + <div class="bf-icon-wrap" style="font-size:30px; vertical-align: 15px;" aria-hidden="true"><i class="fa fa-cloud"></i><i style="font-size:15px; vertical-align: 15px;" class="fa fa-exchange fa-8x"></i><i class="fa fa-cloud"></i></div> + <h3>Multi-Cluster</h3> + <p>Geode clusters can be replicated over WAN in various topologies: active-active, active-passive, ring, hub-spoke, star, etc.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap" style="font-size:30px; vertical-align: -5px;" aria-hidden="true"><i class="fa fa-bullhorn"></i><i class="fa fa-laptop"></i></div> + <h3>Continuous Query</h3> + <p>Clients can stay up to date by registering OQL queries with the Geode servers, making event-driven applications possible.</p> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap" style="font-size:30px; vertical-align: -5px;" aria-hidden="true"><i class="fa fa-desktop"></i><i class="fa fa-laptop"></i></div> + <h3>Clients</h3> + <p>Clients are available for Java. (C++, C# .NET and Node.js coming soon.) A REST API is available for all other languages.</p> + </div> + </div> + <div class="row"> + <div class="col-md-4"> + <div></div> + </div> + <div class="col-md-4"> + <div class="bf-icon-wrap" style="font-size:65px; vertical-align: -5px;" aria-hidden="true"><i class="fa fa-plug"></i></div> + <h3>Adapters</h3> + <p>Geode can be used as a drop-in replacement for Redis and memcached, allowing users of these caches to use Geode's server-side features like multi-cluster replication.</p> + </div> + <div class="col-md-4"> + <div></div> + </div> + </div> + + </div> + + </div> +</section> + +<section class="bf-questions"> + <div class="container"> + <div class="col-md-12 text-center cta"> + And much more... Interested? You can check our <a href="https://cwiki.apache.org/confluence/display/GEODE/Index#Index-Geodein5minutesGeodein5minutes" target="_blank" class="btn btn-inverse btn-lg">Geode in 5 minutes tutorial</a> <span class="avoidwrap">, ask a question on the <a href="/community/" class="btn btn-inverse btn-lg">Mailing lists</a> or <a href="http://stackoverflow.com/search?q=Apache%20Geode" class="btn btn-inverse btn-lg">StackOverflow</a></span> + </div> + </div> +</section + +<section class="bf-news"> + <div class="container"> + + <div class="row"> + <div class="col-md-12 text-left"> + <h2>About the Project</h2> +<p>Apache Geode is a data management platform that provides real-time, consistent access to data-intensive applications throughout widely distributed cloud architectures.</p> + +<p>Geode pools memory, CPU, network resources, and optionally local disk across multiple processes +to manage application objects and behavior. It uses dynamic replication and data partitioning +techniques to implement high availability, improved performance, scalability, and fault +tolerance. In addition to being a distributed data container, Apache Geode is an in-memory data +management system that provides reliable asynchronous event notifications and guaranteed message +delivery.</p> + +<p>Apache Geode is a mature, robust technology originally developed by GemStone Systems. +Commercially available as GemFireâ¢, it was first deployed in the financial sector as the transactional, low-latency data engine used +in Wall Street trading platforms. +Today Apache Geode technology is used by hundreds of enterprise customers for high-scale business applications that must meet low latency and 24x7 availability requirements.</p> + </div> + <!-- + <div class="col-md-4 text-left"> + <h2>Recent Releases</h2> + + + </div> + --> + </div> + + </div> +</section> + + +<footer class="bf-footer" role="contentinfo"> + <div class="container"> + <div class="row"> + <div class="col-md-2"> + <ul class="nav nav-list"> + <li class="nav-header"><a href="/">Home</a></li> + <li class="nav-header"><a href="/community/">Community</a></li> + <li><a href="/community/#events">Events</a></li> + <li><a href="/community/#mailing-lists">Mailing Lists</a></li> + <li><a href="/community/#deployments">Deployments</a></li> + <!-- <li><a href="/community/#committers">Commiters</a></li> --> + </ul> + </div> + <div class="col-md-2"> + <ul class="nav nav-list"> + <li class="nav-header"><a href="http://github.com/apache/geode" target="_blank">Code</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/Project+Proposals+and+Specifications" target="_blank">Specifications</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/Geode+Internal+Architecture" target="_blank">Internal Architecture</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/Writing+tests" target="_blank">Writing Tests</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/Criteria+for+Code+Submissions" target="_blank">Code Submissions</a></li> + </ul> + </div> + <div class="col-md-2"> + <ul class="nav nav-list"> + <li class="nav-header">Resources</li> + <li><a href="http://github.com/apache/geode" target="_blank">GitHub Code</a></li> + <li><a href="/docs/">Docs</a></li> + <li><a href="https://issues.apache.org/jira/browse/GEODE" target="_blank">JIRA Bug Tracker</a></li> + <li><a href="http://stackoverflow.com/search?q=Apache%20Geode" target="_blank">StackOverflow</a></li> + <li><a href="/community/#live">Live Chat</a></li> + <li><a href="https://twitter.com/apachegeode" target="_blank">Twitter</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/Index#Index-Geodein5minutesGeodein5minutes" target="_blank">Geode in 5 minutes</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/How+to+Contribute" target="_blank">How to Contribute</a></li> + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/Application+Development" target="_blank">Application Development</a></li> + + <li><a href="https://cwiki.apache.org/confluence/display/GEODE/Technology+FAQ" target="_blank">FAQ</a></li> + + </ul> + </div> + <div class="col-md-2"> + <ul class="nav nav-list"> + <li class="nav-header">Apache</li> + <li><a href="http://www.apache.org/licenses/" target="_blank">License</a></li> + <li><a href="http://www.apache.org/foundation/sponsorship.html" target="_blank">Sponsorship</a></li> + <li><a href="http://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a></li> + <li><a href="http://www.apache.org/security/">Security</a></li> + <li><a href="http://www.apache.org/" target="_blank">Apache Foundation</a></li> + </ul> + </div> + <div class="col-md-4"> + <a class="twitter-timeline" href="https://twitter.com/search?q=%23ApacheGeode%20OR%20Apache%20Geode" data-widget-id="665030887004725248">Tweets about #ApacheGeode OR Apache Geode</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> + </div> + <!-- + <div class="col-md-4"> + <div class="input-group form-search"> + <input type="text" class="form-control search-query"> + <span class="input-group-btn"> + <button type="submit" class="btn btn-primary" data-type="last">Search</button> + </span> + </div> + </div> --> + </div> + <div class="row"> + <center> + <div id="copyright"> + <a href="http://www.apache.org" target="_blank"><img src="/img/asf_logo.png" height="125"></a><br/><br/> + <p>Copyright © 2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.<br> + Apache, Apache Geode, and the Apache feather logos are trademarks of The Apache Software Foundation.</p> + <p>Site designed & assembled with love by <a href="https://github.com/ryuneeee">@ryuneeee</a> + <a href="https://github.com/realbeast">@realbeast</a> + <a href="https://twitter.com/timanglade">@timanglade</a> + <a href="https://twitter.com/snoopdave">@snoopdave</a> for Apache Usergrid.</p> + <p>Modified for Apache Geode by <a href="https://twitter.com/william_markito">@william_markito</a>.</p> + </div> + </center> + </div> + </div> +</footer> + +<script type="text/javascript" src="/js/head.js"></script> +<script type="text/javascript"> + head.js("/js/jquery-1.10.1.min.js", "/js/bootstrap.min.js", "/js/usergrid-site.js"); +</script> + + + +</body> +</html> http://git-wip-us.apache.org/repos/asf/geode-site/blob/a646ed21/build/content/javascripts/all.js ---------------------------------------------------------------------- diff --git a/build/content/javascripts/all.js b/build/content/javascripts/all.js new file mode 100644 index 0000000..7300c7e --- /dev/null +++ b/build/content/javascripts/all.js @@ -0,0 +1,1085 @@ +(function() { + var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; + + function toggleClass(el, className) { + var check = new RegExp("\\b" + className + "\\b"); + if (check.test(el.className)) { + el.className = el.className.replace(check, ''); + } else { + el.className += ' ' + className; + } + } + + function openSubmenu(e) { + if (e.target.tagName !== 'A') { + var el = e.currentTarget; + toggleClass(el, 'expanded'); + e.stopPropagation(); + } + } + + function registerOnClick(el, handler) { + if (el.addEventListener) { + el.addEventListener('click', handler); + } else { + el.onclick = handler; + } + } + + function toggleMainMenu(e) { + var el = e.currentTarget; + toggleClass(el.parentNode, 'menu-active'); + } + + function toggleSubMenu(e) { + var el = e.currentTarget; + toggleClass(el.parentNode, 'active'); + } + + function displayDate(millis) { + millis = parseInt(millis, 10); + var date = new Date(millis); + + return [MONTHS[date.getMonth()], ' ', date.getDate(), ', ', date.getFullYear()].join(''); + } + + function maybeOpenNewWindow(e) { + var el = e.currentTarget; + var href = el.href; + + if (Bookbinder.needsNewWindow(e, href, window.location.host)) { + e.preventDefault(); + e.stopPropagation(); + window.open(href); + } + } + + window.Bookbinder = { + startSidenav: function(rootEl, currentPath) { + if (!rootEl) { return; } + + var submenus = rootEl.querySelectorAll('.has_submenu'); + + for (var i = 0; i < submenus.length; i++) { + registerOnClick(submenus[i], openSubmenu); + } + + if (currentPath) { + var currentLink = rootEl.querySelector('a[href="' + currentPath + '"]'); + if (currentLink) { + currentLink.className += ' active'; + + var hasSubmenu = /\bhas_submenu\b/; + var subnavLocation = currentLink.parentNode; + + while(subnavLocation.parentNode !== rootEl) { + subnavLocation = subnavLocation.parentNode; + if (hasSubmenu.test(subnavLocation.className)) { + subnavLocation.className += ' expanded'; + } + } + + rootEl.scrollTop = currentLink.offsetTop - rootEl.offsetTop; + } + } + }, + mobileMainMenu: function(root) { + var mainMenus = root.querySelectorAll('[data-behavior=MenuMobile]'); + + for (var i = 0; i < mainMenus.length; i++) { + registerOnClick(mainMenus[i], toggleMainMenu); + } + }, + mobileSubMenu: function(root) { + var subMenus = root.querySelectorAll('[data-behavior=SubMenuMobile]'); + + for (var i = 0; i < subMenus.length; i++) { + registerOnClick(subMenus[i], toggleSubMenu); + } + }, + modifiedDates: function(root) { + var datesElements = root.querySelectorAll('[data-behavior=DisplayModifiedDate]'); + + for (var i = 0; i < datesElements.length; i++) { + datesElements[i].innerText = displayDate(datesElements[i].getAttribute('data-modified-date')); + } + }, + externalLinks: function(root) { + var links = root.querySelectorAll('a[href]'); + + for (var i = 0; i < links.length; i++) { + registerOnClick(links[i], maybeOpenNewWindow); + } + }, + needsNewWindow: function(e, destinationUrl, currentDomain) { + if (e.button !== 0 || e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) { + return false; + } + + var destinationDomain = destinationUrl.replace(/^https?:\/\//, '').split('/')[0]; + return destinationDomain !== currentDomain; + }, + boot: function() { + Bookbinder.startSidenav(document.querySelector('#sub-nav'), document.location.pathname); + Bookbinder.mobileMainMenu(document); + Bookbinder.mobileSubMenu(document); + Bookbinder.modifiedDates(document); + Bookbinder.externalLinks(document); + } + }; +})(); +//Licensed to the Apache Software Foundation (ASF) under one or more +//contributor license agreements. See the NOTICE file distributed with +//this work for additional information regarding copyright ownership. +//The ASF licenses this file to You under the Apache License, Version 2.0 +//(the "License"); you may not use this file except in compliance with +//the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +//express or implied. See the License for the specific language governing +//permissions and limitations under the License. + +(function() { + 'use strict' + + var keyCounter = 0 + var allWaypoints = {} + + /* http://imakewebthings.com/waypoints/api/waypoint */ + function Waypoint(options) { + if (!options) { + throw new Error('No options passed to Waypoint constructor') + } + if (!options.element) { + throw new Error('No element option passed to Waypoint constructor') + } + if (!options.handler) { + throw new Error('No handler option passed to Waypoint constructor') + } + + this.key = 'waypoint-' + keyCounter + this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) + this.element = this.options.element + this.adapter = new Waypoint.Adapter(this.element) + this.callback = options.handler + this.axis = this.options.horizontal ? 'horizontal' : 'vertical' + this.enabled = this.options.enabled + this.triggerPoint = null + this.group = Waypoint.Group.findOrCreate({ + name: this.options.group, + axis: this.axis + }) + this.context = Waypoint.Context.findOrCreateByElement(this.options.context) + + if (Waypoint.offsetAliases[this.options.offset]) { + this.options.offset = Waypoint.offsetAliases[this.options.offset] + } + this.group.add(this) + this.context.add(this) + allWaypoints[this.key] = this + keyCounter += 1 + } + + /* Private */ + Waypoint.prototype.queueTrigger = function(direction) { + this.group.queueTrigger(this, direction) + } + + /* Private */ + Waypoint.prototype.trigger = function(args) { + if (!this.enabled) { + return + } + if (this.callback) { + this.callback.apply(this, args) + } + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/destroy */ + Waypoint.prototype.destroy = function() { + this.context.remove(this) + this.group.remove(this) + delete allWaypoints[this.key] + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/disable */ + Waypoint.prototype.disable = function() { + this.enabled = false + return this + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/enable */ + Waypoint.prototype.enable = function() { + this.context.refresh() + this.enabled = true + return this + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/next */ + Waypoint.prototype.next = function() { + return this.group.next(this) + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/previous */ + Waypoint.prototype.previous = function() { + return this.group.previous(this) + } + + /* Private */ + Waypoint.invokeAll = function(method) { + var allWaypointsArray = [] + for (var waypointKey in allWaypoints) { + allWaypointsArray.push(allWaypoints[waypointKey]) + } + for (var i = 0, end = allWaypointsArray.length; i < end; i++) { + allWaypointsArray[i][method]() + } + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/destroy-all */ + Waypoint.destroyAll = function() { + Waypoint.invokeAll('destroy') + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/disable-all */ + Waypoint.disableAll = function() { + Waypoint.invokeAll('disable') + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/enable-all */ + Waypoint.enableAll = function() { + Waypoint.invokeAll('enable') + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/refresh-all */ + Waypoint.refreshAll = function() { + Waypoint.Context.refreshAll() + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/viewport-height */ + Waypoint.viewportHeight = function() { + return window.innerHeight || document.documentElement.clientHeight + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/viewport-width */ + Waypoint.viewportWidth = function() { + return document.documentElement.clientWidth + } + + Waypoint.adapters = [] + + Waypoint.defaults = { + context: window, + continuous: true, + enabled: true, + group: 'default', + horizontal: false, + offset: 0 + } + + Waypoint.offsetAliases = { + 'bottom-in-view': function() { + return this.context.innerHeight() - this.adapter.outerHeight() + }, + 'right-in-view': function() { + return this.context.innerWidth() - this.adapter.outerWidth() + } + } + + window.Waypoint = Waypoint +}()) +; +//Licensed to the Apache Software Foundation (ASF) under one or more +//contributor license agreements. See the NOTICE file distributed with +//this work for additional information regarding copyright ownership. +//The ASF licenses this file to You under the Apache License, Version 2.0 +//(the "License"); you may not use this file except in compliance with +//the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +//express or implied. See the License for the specific language governing +//permissions and limitations under the License. + +(function() { + 'use strict' + + function requestAnimationFrameShim(callback) { + window.setTimeout(callback, 1000 / 60) + } + + var keyCounter = 0 + var contexts = {} + var Waypoint = window.Waypoint + var oldWindowLoad = window.onload + + /* http://imakewebthings.com/waypoints/api/context */ + function Context(element) { + this.element = element + this.Adapter = Waypoint.Adapter + this.adapter = new this.Adapter(element) + this.key = 'waypoint-context-' + keyCounter + this.didScroll = false + this.didResize = false + this.oldScroll = { + x: this.adapter.scrollLeft(), + y: this.adapter.scrollTop() + } + this.waypoints = { + vertical: {}, + horizontal: {} + } + + element.waypointContextKey = this.key + contexts[element.waypointContextKey] = this + keyCounter += 1 + + this.createThrottledScrollHandler() + this.createThrottledResizeHandler() + } + + /* Private */ + Context.prototype.add = function(waypoint) { + var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' + this.waypoints[axis][waypoint.key] = waypoint + this.refresh() + } + + /* Private */ + Context.prototype.checkEmpty = function() { + var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) + var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) + if (horizontalEmpty && verticalEmpty) { + this.adapter.off('.waypoints') + delete contexts[this.key] + } + } + + /* Private */ + Context.prototype.createThrottledResizeHandler = function() { + var self = this + + function resizeHandler() { + self.handleResize() + self.didResize = false + } + + this.adapter.on('resize.waypoints', function() { + if (!self.didResize) { + self.didResize = true + Waypoint.requestAnimationFrame(resizeHandler) + } + }) + } + + /* Private */ + Context.prototype.createThrottledScrollHandler = function() { + var self = this + function scrollHandler() { + self.handleScroll() + self.didScroll = false + } + + this.adapter.on('scroll.waypoints', function() { + if (!self.didScroll || Waypoint.isTouch) { + self.didScroll = true + Waypoint.requestAnimationFrame(scrollHandler) + } + }) + } + + /* Private */ + Context.prototype.handleResize = function() { + Waypoint.Context.refreshAll() + } + + /* Private */ + Context.prototype.handleScroll = function() { + var triggeredGroups = {} + var axes = { + horizontal: { + newScroll: this.adapter.scrollLeft(), + oldScroll: this.oldScroll.x, + forward: 'right', + backward: 'left' + }, + vertical: { + newScroll: this.adapter.scrollTop(), + oldScroll: this.oldScroll.y, + forward: 'down', + backward: 'up' + } + } + + for (var axisKey in axes) { + var axis = axes[axisKey] + var isForward = axis.newScroll > axis.oldScroll + var direction = isForward ? axis.forward : axis.backward + + for (var waypointKey in this.waypoints[axisKey]) { + var waypoint = this.waypoints[axisKey][waypointKey] + var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint + var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint + var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint + var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint + if (crossedForward || crossedBackward) { + waypoint.queueTrigger(direction) + triggeredGroups[waypoint.group.id] = waypoint.group + } + } + } + + for (var groupKey in triggeredGroups) { + triggeredGroups[groupKey].flushTriggers() + } + + this.oldScroll = { + x: axes.horizontal.newScroll, + y: axes.vertical.newScroll + } + } + + /* Private */ + Context.prototype.innerHeight = function() { + /*eslint-disable eqeqeq */ + if (this.element == this.element.window) { + return Waypoint.viewportHeight() + } + /*eslint-enable eqeqeq */ + return this.adapter.innerHeight() + } + + /* Private */ + Context.prototype.remove = function(waypoint) { + delete this.waypoints[waypoint.axis][waypoint.key] + this.checkEmpty() + } + + /* Private */ + Context.prototype.innerWidth = function() { + /*eslint-disable eqeqeq */ + if (this.element == this.element.window) { + return Waypoint.viewportWidth() + } + /*eslint-enable eqeqeq */ + return this.adapter.innerWidth() + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/context-destroy */ + Context.prototype.destroy = function() { + var allWaypoints = [] + for (var axis in this.waypoints) { + for (var waypointKey in this.waypoints[axis]) { + allWaypoints.push(this.waypoints[axis][waypointKey]) + } + } + for (var i = 0, end = allWaypoints.length; i < end; i++) { + allWaypoints[i].destroy() + } + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/context-refresh */ + Context.prototype.refresh = function() { + /*eslint-disable eqeqeq */ + var isWindow = this.element == this.element.window + /*eslint-enable eqeqeq */ + var contextOffset = isWindow ? undefined : this.adapter.offset() + var triggeredGroups = {} + var axes + + this.handleScroll() + axes = { + horizontal: { + contextOffset: isWindow ? 0 : contextOffset.left, + contextScroll: isWindow ? 0 : this.oldScroll.x, + contextDimension: this.innerWidth(), + oldScroll: this.oldScroll.x, + forward: 'right', + backward: 'left', + offsetProp: 'left' + }, + vertical: { + contextOffset: isWindow ? 0 : contextOffset.top, + contextScroll: isWindow ? 0 : this.oldScroll.y, + contextDimension: this.innerHeight(), + oldScroll: this.oldScroll.y, + forward: 'down', + backward: 'up', + offsetProp: 'top' + } + } + + for (var axisKey in axes) { + var axis = axes[axisKey] + for (var waypointKey in this.waypoints[axisKey]) { + var waypoint = this.waypoints[axisKey][waypointKey] + var adjustment = waypoint.options.offset + var oldTriggerPoint = waypoint.triggerPoint + var elementOffset = 0 + var freshWaypoint = oldTriggerPoint == null + var contextModifier, wasBeforeScroll, nowAfterScroll + var triggeredBackward, triggeredForward + + if (waypoint.element !== waypoint.element.window) { + elementOffset = waypoint.adapter.offset()[axis.offsetProp] + } + + if (typeof adjustment === 'function') { + adjustment = adjustment.apply(waypoint) + } + else if (typeof adjustment === 'string') { + adjustment = parseFloat(adjustment) + if (waypoint.options.offset.indexOf('%') > - 1) { + adjustment = Math.ceil(axis.contextDimension * adjustment / 100) + } + } + + contextModifier = axis.contextScroll - axis.contextOffset + waypoint.triggerPoint = elementOffset + contextModifier - adjustment + wasBeforeScroll = oldTriggerPoint < axis.oldScroll + nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll + triggeredBackward = wasBeforeScroll && nowAfterScroll + triggeredForward = !wasBeforeScroll && !nowAfterScroll + + if (!freshWaypoint && triggeredBackward) { + waypoint.queueTrigger(axis.backward) + triggeredGroups[waypoint.group.id] = waypoint.group + } + else if (!freshWaypoint && triggeredForward) { + waypoint.queueTrigger(axis.forward) + triggeredGroups[waypoint.group.id] = waypoint.group + } + else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { + waypoint.queueTrigger(axis.forward) + triggeredGroups[waypoint.group.id] = waypoint.group + } + } + } + + Waypoint.requestAnimationFrame(function() { + for (var groupKey in triggeredGroups) { + triggeredGroups[groupKey].flushTriggers() + } + }) + + return this + } + + /* Private */ + Context.findOrCreateByElement = function(element) { + return Context.findByElement(element) || new Context(element) + } + + /* Private */ + Context.refreshAll = function() { + for (var contextId in contexts) { + contexts[contextId].refresh() + } + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/context-find-by-element */ + Context.findByElement = function(element) { + return contexts[element.waypointContextKey] + } + + window.onload = function() { + if (oldWindowLoad) { + oldWindowLoad() + } + Context.refreshAll() + } + + Waypoint.requestAnimationFrame = function(callback) { + var requestFn = window.requestAnimationFrame || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || + requestAnimationFrameShim + requestFn.call(window, callback) + } + Waypoint.Context = Context +}()) +; +//Licensed to the Apache Software Foundation (ASF) under one or more +//contributor license agreements. See the NOTICE file distributed with +//this work for additional information regarding copyright ownership. +//The ASF licenses this file to You under the Apache License, Version 2.0 +//(the "License"); you may not use this file except in compliance with +//the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +//express or implied. See the License for the specific language governing +//permissions and limitations under the License. + +(function() { + 'use strict' + + function byTriggerPoint(a, b) { + return a.triggerPoint - b.triggerPoint + } + + function byReverseTriggerPoint(a, b) { + return b.triggerPoint - a.triggerPoint + } + + var groups = { + vertical: {}, + horizontal: {} + } + var Waypoint = window.Waypoint + + /* http://imakewebthings.com/waypoints/api/group */ + function Group(options) { + this.name = options.name + this.axis = options.axis + this.id = this.name + '-' + this.axis + this.waypoints = [] + this.clearTriggerQueues() + groups[this.axis][this.name] = this + } + + /* Private */ + Group.prototype.add = function(waypoint) { + this.waypoints.push(waypoint) + } + + /* Private */ + Group.prototype.clearTriggerQueues = function() { + this.triggerQueues = { + up: [], + down: [], + left: [], + right: [] + } + } + + /* Private */ + Group.prototype.flushTriggers = function() { + for (var direction in this.triggerQueues) { + var waypoints = this.triggerQueues[direction] + var reverse = direction === 'up' || direction === 'left' + waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) + for (var i = 0, end = waypoints.length; i < end; i += 1) { + var waypoint = waypoints[i] + if (waypoint.options.continuous || i === waypoints.length - 1) { + waypoint.trigger([direction]) + } + } + } + this.clearTriggerQueues() + } + + /* Private */ + Group.prototype.next = function(waypoint) { + this.waypoints.sort(byTriggerPoint) + var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) + var isLast = index === this.waypoints.length - 1 + return isLast ? null : this.waypoints[index + 1] + } + + /* Private */ + Group.prototype.previous = function(waypoint) { + this.waypoints.sort(byTriggerPoint) + var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) + return index ? this.waypoints[index - 1] : null + } + + /* Private */ + Group.prototype.queueTrigger = function(waypoint, direction) { + this.triggerQueues[direction].push(waypoint) + } + + /* Private */ + Group.prototype.remove = function(waypoint) { + var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) + if (index > -1) { + this.waypoints.splice(index, 1) + } + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/first */ + Group.prototype.first = function() { + return this.waypoints[0] + } + + /* Public */ + /* http://imakewebthings.com/waypoints/api/last */ + Group.prototype.last = function() { + return this.waypoints[this.waypoints.length - 1] + } + + /* Private */ + Group.findOrCreate = function(options) { + return groups[options.axis][options.name] || new Group(options) + } + + Waypoint.Group = Group +}()) +; +//Licensed to the Apache Software Foundation (ASF) under one or more +//contributor license agreements. See the NOTICE file distributed with +//this work for additional information regarding copyright ownership. +//The ASF licenses this file to You under the Apache License, Version 2.0 +//(the "License"); you may not use this file except in compliance with +//the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +//express or implied. See the License for the specific language governing +//permissions and limitations under the License. + +(function() { + 'use strict' + + var Waypoint = window.Waypoint + + function isWindow(element) { + return element === element.window + } + + function getWindow(element) { + if (isWindow(element)) { + return element + } + return element.defaultView + } + + function classNameRegExp(className) { + return new RegExp("\\b" + className + "\\b"); + } + + function NoFrameworkAdapter(element) { + this.element = element + this.handlers = {} + } + + NoFrameworkAdapter.prototype.innerHeight = function() { + var isWin = isWindow(this.element) + return isWin ? this.element.innerHeight : this.element.clientHeight + } + + NoFrameworkAdapter.prototype.innerWidth = function() { + var isWin = isWindow(this.element) + return isWin ? this.element.innerWidth : this.element.clientWidth + } + + NoFrameworkAdapter.prototype.off = function(event, handler) { + function removeListeners(element, listeners, handler) { + for (var i = 0, end = listeners.length - 1; i < end; i++) { + var listener = listeners[i] + if (!handler || handler === listener) { + element.removeEventListener(listener) + } + } + } + + var eventParts = event.split('.') + var eventType = eventParts[0] + var namespace = eventParts[1] + var element = this.element + + if (namespace && this.handlers[namespace] && eventType) { + removeListeners(element, this.handlers[namespace][eventType], handler) + this.handlers[namespace][eventType] = [] + } + else if (eventType) { + for (var ns in this.handlers) { + removeListeners(element, this.handlers[ns][eventType] || [], handler) + this.handlers[ns][eventType] = [] + } + } + else if (namespace && this.handlers[namespace]) { + for (var type in this.handlers[namespace]) { + removeListeners(element, this.handlers[namespace][type], handler) + } + this.handlers[namespace] = {} + } + } + + /* Adapted from jQuery 1.x offset() */ + NoFrameworkAdapter.prototype.offset = function() { + if (!this.element.ownerDocument) { + return null + } + + var documentElement = this.element.ownerDocument.documentElement + var win = getWindow(this.element.ownerDocument) + var rect = { + top: 0, + left: 0 + } + + if (this.element.getBoundingClientRect) { + rect = this.element.getBoundingClientRect() + } + + return { + top: rect.top + win.pageYOffset - documentElement.clientTop, + left: rect.left + win.pageXOffset - documentElement.clientLeft + } + } + + NoFrameworkAdapter.prototype.on = function(event, handler) { + var eventParts = event.split('.') + var eventType = eventParts[0] + var namespace = eventParts[1] || '__default' + var nsHandlers = this.handlers[namespace] = this.handlers[namespace] || {} + var nsTypeList = nsHandlers[eventType] = nsHandlers[eventType] || [] + + nsTypeList.push(handler) + this.element.addEventListener(eventType, handler) + } + + NoFrameworkAdapter.prototype.outerHeight = function(includeMargin) { + var height = this.innerHeight() + var computedStyle + + if (includeMargin && !isWindow(this.element)) { + computedStyle = window.getComputedStyle(this.element) + height += parseInt(computedStyle.marginTop, 10) + height += parseInt(computedStyle.marginBottom, 10) + } + + return height + } + + NoFrameworkAdapter.prototype.outerWidth = function(includeMargin) { + var width = this.innerWidth() + var computedStyle + + if (includeMargin && !isWindow(this.element)) { + computedStyle = window.getComputedStyle(this.element) + width += parseInt(computedStyle.marginLeft, 10) + width += parseInt(computedStyle.marginRight, 10) + } + + return width + } + + NoFrameworkAdapter.prototype.scrollLeft = function() { + var win = getWindow(this.element) + return win ? win.pageXOffset : this.element.scrollLeft + } + + NoFrameworkAdapter.prototype.scrollTop = function() { + var win = getWindow(this.element) + return win ? win.pageYOffset : this.element.scrollTop + } + + NoFrameworkAdapter.prototype.height = function(newHeight) { + this.element.style.height = newHeight; + } + + NoFrameworkAdapter.prototype.removeClass = function(className) { + this.element.className = this.element.className.replace(classNameRegExp(className), ''); + } + + NoFrameworkAdapter.prototype.toggleClass = function(className, addClass) { + var check = classNameRegExp(className); + if (check.test(this.element.className)) { + if (!addClass) { + this.removeClass(className); + } + } else { + this.element.className += ' ' + className; + } + } + + NoFrameworkAdapter.prototype.parent = function() { + return new NoFrameworkAdapter(this.element.parentNode); + } + + NoFrameworkAdapter.prototype.wrap = function(wrapper) { + this.element.insertAdjacentHTML('beforebegin', wrapper) + var wrapperNode = this.element.previousSibling + this.element.parentNode.removeChild(this.element) + wrapperNode.appendChild(this.element) + } + + NoFrameworkAdapter.extend = function() { + var args = Array.prototype.slice.call(arguments) + + function merge(target, obj) { + if (typeof target === 'object' && typeof obj === 'object') { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + target[key] = obj[key] + } + } + } + + return target + } + + for (var i = 1, end = args.length; i < end; i++) { + merge(args[0], args[i]) + } + return args[0] + } + + NoFrameworkAdapter.inArray = function(element, array, i) { + return array == null ? -1 : array.indexOf(element, i) + } + + NoFrameworkAdapter.isEmptyObject = function(obj) { + /* eslint no-unused-vars: 0 */ + for (var name in obj) { + return false + } + return true + } + + NoFrameworkAdapter.proxy = function(func, obj) { + return function() { + return func.apply(obj, arguments); + } + } + + Waypoint.adapters.push({ + name: 'noframework', + Adapter: NoFrameworkAdapter + }) + Waypoint.Adapter = NoFrameworkAdapter +}()) +; +//Licensed to the Apache Software Foundation (ASF) under one or more +//contributor license agreements. See the NOTICE file distributed with +//this work for additional information regarding copyright ownership. +//The ASF licenses this file to You under the Apache License, Version 2.0 +//(the "License"); you may not use this file except in compliance with +//the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +//express or implied. See the License for the specific language governing +//permissions and limitations under the License. + +(function() { + 'use strict' + + var Waypoint = window.Waypoint; + var adapter = Waypoint.Adapter; + + /* http://imakewebthings.com/waypoints/shortcuts/sticky-elements */ + function Sticky(options) { + this.options = adapter.extend({}, Waypoint.defaults, Sticky.defaults, options) + this.element = this.options.element + this.$element = new adapter(this.element) + this.createWrapper() + this.createWaypoint() + } + + /* Private */ + Sticky.prototype.createWaypoint = function() { + var originalHandler = this.options.handler + + this.waypoint = new Waypoint(adapter.extend({}, this.options, { + element: this.wrapper, + handler: adapter.proxy(function(direction) { + var shouldBeStuck = this.options.direction.indexOf(direction) > -1 + var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : '' + + this.$wrapper.height(wrapperHeight) + this.$element.toggleClass(this.options.stuckClass, shouldBeStuck) + + if (originalHandler) { + originalHandler.call(this, direction) + } + }, this) + })) + } + + /* Private */ + Sticky.prototype.createWrapper = function() { + if (this.options.wrapper) { + this.$element.wrap(this.options.wrapper) + } + this.$wrapper = this.$element.parent() + this.wrapper = this.$wrapper.element + } + + /* Public */ + Sticky.prototype.destroy = function() { + if (this.$element.parent().element === this.wrapper) { + this.waypoint.destroy() + this.$element.removeClass(this.options.stuckClass) + if (this.options.wrapper) { + this.$element.unwrap() + } + } + } + + Sticky.defaults = { + wrapper: '<div class="sticky-wrapper" />', + stuckClass: 'stuck', + direction: 'down right' + } + + Waypoint.Sticky = Sticky +}()) +; +//Licensed to the Apache Software Foundation (ASF) under one or more +//contributor license agreements. See the NOTICE file distributed with +//this work for additional information regarding copyright ownership. +//The ASF licenses this file to You under the Apache License, Version 2.0 +//(the "License"); you may not use this file except in compliance with +//the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +//express or implied. See the License for the specific language governing +//permissions and limitations under the License. + +// Declare your book-specific javascript overrides in this file. + + + + + + +window.onload = function() { + Bookbinder.boot(); + var sticky = new Waypoint.Sticky({ + element: document.querySelector('#js-to-top'), + wrapper: '<div class="sticky-wrapper" />', + stuckClass: 'sticky', + offset: 100 + }); +} +; + +