Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 15 commits
  • 10 files changed
  • 0 commit comments
  • 1 contributor
View
8 _layouts/default.html
@@ -9,6 +9,7 @@
{% endif %}
</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript">var _sf_startpt=(new Date()).getTime()</script>
<link rel="stylesheet" href="/css/base.css" type="text/css" />
@@ -46,6 +47,13 @@
{{ content }}
</div><!-- /.main -->
+ <script type="text/javascript" src="/js/fastclick.js"></script>
+ <script type="text/javascript">
+ window.addEventListener('load', function() {
+ new FastClick(document.body);
+ }, false);
+ </script>
+
<script type="text/javascript">
(function() {
var t = document.createElement('script');
View
12 _layouts/link.html
@@ -0,0 +1,12 @@
+---
+layout: default
+---
+<p class="date">{{ page.date | date: "%B %e, %Y" }}</p>
+<h1 class="link"><span class="desc">Link:</span> <a href="{{ page.link }}">{{ page.title }}</a></h1>
+{{ content }}
+
+<div class="keep-in-touch">
+ <p>
+ If you'd like to keep in touch, I tweet <a href="https://twitter.com/kneath">@kneath</a> on Twitter. You're also welcome to send a polite email to <a href="mailto:kneath@gmail.com">kneath@gmail.com</a>. I don't always get the chance to respond, but email is always the best way to get in touch.
+ </p>
+</div>
View
27 _posts/2012-12-03-dumb-software.md
@@ -0,0 +1,27 @@
+---
+layout: post
+title: "Dumb software"
+summary: An ode to dumb software, my favorite kind.
+excerpt:
+ There is a beauty to dumb software. These things like HTML, CSS and JavaScript. Things like Unix, C and SQL. Plain text files, email, and GIFs. They're fun to work with. They always work. There's no caveats. I just love them so damn much.
+---
+
+There is a beauty to dumb software. These things like HTML, CSS and JavaScript. Things like Unix, C and SQL. Plain text files, email, and GIFs. They're fun to work with. They always work. There's no caveats. I just love them so damn much.
+
+But wait until you see the light! Software today is intelligent! Asynchronous front ends generated from esoteric scripting languages running on clusters of distributed virtual machines around the globe! Death to repetition! It's more productive! It's scalable! It's fault tolerant!
+
+I followed the light and it only ended in darkness.
+
+----
+
+Intelligent systems have dark corners. Why didn't it work this time? It's hard to see everything. I'm not sure what it's doing. This is impossible! Is there even a bug, or have I simply lost my mind?
+
+<blockquote class="twitter-tweet tw-align-center"><p>The problem with ARC is it's hard to verify the difference between you losing your mind and an ARC bug.</p>&mdash; Josh Abernathy (@joshaber) <a href="https://twitter.com/joshaber/status/274717093486800896" data-datetime="2012-12-01T03:30:33+00:00">December 1, 2012</a></blockquote>
+<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
+
+Dumb systems are obvious. It's obviously doing something dumb — too much work, too inflexible. But the work is predictable. It's obviously doing too much work. I can see everything.
+
+Dumb software can do great things. It put humankind on the Moon. [It got us to Mars](http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf). To me, it feels like the dumber the software, the more it accomplishes.
+
+I want to create great things. And sometimes it just feels right to build a simple little static website with HTML, CSS, and JavaScript.
+
View
16 _posts/2012-12-09-link-jigsaws-are-better.md
@@ -0,0 +1,16 @@
+---
+layout: link
+title: "Jigsaws are better"
+type: link
+link: http://www.perfect-flow.com/blog/boxes2/
+---
+
+On the subject of repair scheduling:
+
+ > Repairs scheduling is fundamentally flawed. Maintenance companies try to shoehorn irregular shaped jobs into nice, standardised boxes and it leads to appointments being missed and repairs left unfinished. The company wants its’ customers to be compliant and flexible, but customers need the opposite to be true. So how do we fix the system?
+
+Great article on systems design. The system is more efficient and it makes customers happier. The end result is even simpler than it started:
+
+ > We ask the customer when they want us to turn up and we give operatives all the time and materials they need to complete the right fix.
+
+ Love it.
View
47 _posts/2013-01-04-patent-reasoning.md
@@ -0,0 +1,47 @@
+---
+layout: post
+title: "Patent reasoning"
+summary: In which the entire situation is just fucked. Let's make it better.
+excerpt:
+ In which the entire situation is just fucked. Let's make it better.
+---
+
+Software patents are incredibly difficult to enforce.
+
+As software becomes more complex, patents become more difficult to decipher. Only expert software engineers can truly understand the intended meaning of modern software patents.
+
+As the total number of software patents increase over time, legislation and litigation of software patents become more complex. Only expert lawyers can successfully litigate patents.
+
+Very few expert lawyers are also expert software engineers.
+
+## Big Software vs small software
+
+It's generally understood that the benefit of software patents is to ensure mutually assured destruction amongst competitors. If a competitor sues you over a patent, you countersue with your own patents.
+
+The majority of software companies are small compared to Big Software — companies like IBM, Google, and Apple. Small software competes directly with Big Software.
+
+In a race for patents, it is impossible for a small software company to catch up to the breadth of patents of a Big Software company. Big Software have large patent portfolios and can continue to create patents at the same (or faster) rate than small software.
+
+It is not feasible for a small software company to generate a more effective patent portfolio than a Big Software company.
+
+## Patent trolls
+
+Patent portfolios are known to be ineffective against patent trolls. Patent trolls are small companies or individuals who own very few unused patents (often one) and sue companies hoping for a large payout.
+
+Mutually assured destruction does not apply since the individual has nothing to lose.
+
+## Lawyers
+
+Lawyers make a lot of money off patents.
+
+They make money advising companies on patents. They make money creating them. They make money legislating them. They make money litigating them. Lawyers win on both sides during patent disputes.
+
+It costs software companies time and money to create and manage patents. Time and money not spent on products.
+
+There isn't a single downside to patents from a lawyer's perspective. They create a dependency system that benefits lawyers.
+
+## An obvious conclusion
+
+I've yet to see a single argument that software patents benefit small software companies in any way.
+
+The US Patent Office is [holding a series of round table discussions about software patents](http://www.groklaw.net/article.php?story=20130104012214868). I encourage you to participate.
View
109 _posts/2013-01-07-software-lessons-2012.md
@@ -0,0 +1,109 @@
+---
+layout: post
+title: "What I've learned about building software so far"
+summary: In which the entire situation is just fucked. Let's make it better.
+excerpt:
+ In which the entire situation is just fucked. Let's make it better.
+---
+
+Generally speaking, software companies all work the same way — based in hierarchy, delegation, siloing, hours, and deadlines. This is not a bad way to build software. But it's only one way.
+
+The art and science of **building software** is an interesting one, and one that's near and dear to my heart. It's my job to build software every day, so it's obvious that I care about it. But more importantly, it's my job to figure out the best *way* to build software. GitHub may be a website or a collection of features to some people, but to me it's a tool that lets you build software in the ***GitHub Way***.
+
+In this persuit I've learned a lot about what it means to build high quality software efficiently. All of this has worked out really well for me so far, but as with anything GitHub: everything changes.
+
+## Open source
+
+Open source works dramatically different than almost all software companies. Open source, which powers much of our world. Open source, which produces astonishingly high quality software. Open source, which produces software at a faster rate than any other organization on Earth.
+
+Open source, which has no financial incentive to produce software at all. Yet does so better than anyone else.
+
+## Structure
+
+We model our internal structure after open source. All our code is visible to all employees, and we're accepting patches. Why complain when you can fork it and send a pull request?
+
+Each major project has a group of core maintainers that have their own mailing lists, their own chat rooms, and their own conferences (we call them mini-summits). Smaller projects start off chaotically and build structure over time.
+
+Employees gravitate to the projects that overlap their interests with their available time and skills. Some people work on 50 projects at once. Others just one.
+
+Some people really sink their teeth into just one product. These people think about the vision and goals for what a project could be. They spend time selling these goals to the rest of the committers with words, code, design, and presentations.
+
+Some people become enamored with the destruction of any and all friction. They extract libraries, build development toolchains, fire up servers, optimize our network, and spread their effort around hundreds of applications making sure it's all running smoothly.
+
+In a lot of ways this was [inevitable](http://en.wikipedia.org/wiki/Conway's_law). Lucky for us, it's working great.
+
+## Hiring
+
+Hiring has long been one of our greatest assets at GitHub — we tend to take a rational approach in a world where purposeful ignorance remains dominant (pretty lucky for future generations).
+
+I've been lucky enough to struggle through hiring with some of the smartest people I know, and I think I have a much better grip on how to hire well as a result.
+
+### Hiring criteria
+
+Much of our early hiring was done on gut instinct. That's actually a lie — most of our early hiring was done based off years of working with people through open source. But the hires we made past our friends were done almost solely on gut instinct. Now we have a solid criteria for determining whether someone might become a good GitHubber.
+
+* **Taste** is the style of code they write. The aesthetics of their design. The phrasing of their words. The way in which they work. The way in which people perceive support, development, design, documentation, and maintenance.
+
+ We favor optimists, pragmatism, and above all, a relentless customer focus.
+
+* **Shipping** is their ability to technically do their job and produce meaningful work. Their skills in Ruby, HTML, or CSS (developers). Their skills in written English, and email (support). Their coordination and people skills (internal support). But also their inner drive and ability to *produce*. What have they accomplished in the past? Do they have a track record of shipping?
+
+ We favor people who are self driven and do not need constant guidance. We like people who think big, but ship small.
+
+* **Culture** is how they'll interact with other Hubbers. Are you going to butt heads with them all day? Are they going to be your next best friend? How would you feel if you were forced to take a road trip with them? What are their attitudes toward other lifestyles?
+
+Communicating these guidelines has seriously leveled up our hiring ability. Instead of gut-feeling discussion, we now have a solid framework to discuss new hires.
+
+### Effects of hiring on a team
+
+When the founders first approached me about [seriously taking funding](https://github.com/blog/1189-investing-in-github) early in the year, my main concern was that too much money would result in too much hiring.
+
+Lucky(?) for us, the pace of our hiring accelerated naturally to the point of feeling pain long before the funding took place. I feel pretty comfortable that I now have a rational way to explain how to manage the pace of hiring without resorting to fear, uncertainty, and doubt.
+
+* Each human you add increases the communication overhead of the entire team. As your team grows, you must be ready to adapt your communication channels to absorb the load. A communication system that works for 3 people will not work for 20, and conversely a communication system that works for 20 people will not work for 3. This adaption never ends. Every team that starts new must adapt, every team that grows or shrinks must adapt — each time.
+
+ This communication overhead is not a benefit of small teams — it's a benefit of static teams. More communication means more ideas. It means more progress. It's the very nature of creativity.
+
+ This is a known consequence of hiring. Adding people will slow down the team in the short term and require a lot of non-product focused work on communication. Hire too fast, and you risk full scale paralyzation of a team.
+
+ This year we grew from 52 GitHubbers to 140 GitHubbers and the dotcom team grew from around 9 people to around 17 people. Much of my work this year was focused on communication: writing documentation, marketing ideas, discussing issues, documenting design philosophy, workflows, processes, and creating presentations to communicate my dreams.
+
+* Hiring people that you can delegate problems you don't want to solve is ineffective. This is a broken philosophy of most software companies. Junior developers fix bugs. Senior developers create them.
+
+ This creates a leisure class of developers who aren't involved in the actual building and maintenance of real applications. It's a system that appears completely functional to management (who value senior opinions and blame bugs on inexperience). But when viewed as a whole, the system is clearly dysfunctional and produces low quality software.
+
+* Hiring should serve to level up your team. [Ryan Tomayko came up with a great analogy for this](http://youtu.be/mrONxcyQo4E?t=6m30s): managing a baseball club. We try and add people that have skills or traits the team is missing. And never forget the at creativity is born of diversity.
+
+**Hire to increase the potential of your team.** The more potential a team has, the more problems it ends up solving.
+
+### Domain driven design is the only pattern you need
+
+Software can be complex. There is much talk of design patterns, methodologies, and benefits of specific technologies. None of this matters at all (for our object-oriented, dynamic organization).
+
+Focus on your domain. Model your code after what it means. Fuck your SOA and MVC religion, write code that describes what it's doing and you'll go far.
+
+### Technical wankery
+
+Technical wankery is destroying our profession. Hundreds of thousands of developers spend most of their life changing frameworks, upgrading frameworks, changing design patterns, re-designing entire applications, and re-architecting applications.
+
+And at the end of the day they're left with a net loss. In rare cases, with extraordinary engineers, a better solution is reached. This is the severe minority case.
+
+I learned to ignore all of this. Instead, I focus on building product using technology that's already implemented. If NASA can put a man on the moon without changing test frameworks, I'm pretty sure that I can create some pretty amazing software with six month old technology.
+
+Focus as little as possible to your code's structure, and as much time as possible on your customers.
+
+### Caremad driven development
+
+Producing high quality software is extremely difficult. Bugs are inevitable. Security must always be on the mind. Performance degrades. And the better job your software does, the harder it is to keep up with demand.
+
+[Caremad](http://caremad.com) is the best remedy to maintaining high quality software I've ever found. The best example of caremad as a service at GitHub is KOD — King of Developers.
+
+Every week, a new person volunteers to be the KOD. The KOD's primary job is to work closely with Support to dive into the confusing technical problems our users run into.
+
+Almost every person who comes out of their week of KOD immediately spends the next week fixing the biggest problems in our code base. A week of sympathizing with customers does wonders to understand the truly broken pieces of software.
+
+Get people mad enough to care enough to fix the problem.
+
+## Thanks
+
+Rick Bradley, Chris Wanstrath, Ryan Tomayko, Tom Preston-Werner, PJ Hyett, Scott Chacon, Melissa Severini, Brian Doll, John Barnette.
View
2 about/index.md
@@ -11,7 +11,7 @@ title: "About Kyle Neath"
----
-I love to build the future. I believe software will effect a Change in this world (and beyond), and I am going to be part of it. I'm not a deisgner. Not a programmer. Not a manager. I went to school for [Civil Engineering](http://assets.warpspire.com/images/site/degree.jpg), but ended up building things with software instead.
+I love to build the future. I believe software will effect a Change in this world (and beyond), and I am going to be part of it. I'm not a designer. Not a programmer. Not a manager. I went to school for [Civil Engineering](http://assets.warpspire.com/images/site/degree.jpg), but ended up building things with software instead.
I work on product at GitHub. We're creating a better way to design, build, and ship software.
View
82 css/base.css
@@ -92,8 +92,19 @@ ul.nav li {
font-weight: 600;
}
@media only screen and (max-width: 520px) {
+ ul.nav {
+ position: relative;
+ padding-top: 40px;
+ }
ul.nav li {
- margin: 0 7px;
+ margin: 0 4px;
+ font-size: 13px;
+ }
+ ul.nav li.logo {
+ position: absolute;
+ top: 10px;
+ left: 50%;
+ margin-left: -14px;
}
}
ul.nav li a {
@@ -139,6 +150,7 @@ ul.nav li.logo a {
font-size: 30px;
border: none;
}
+
.listing .post h2 a {
color: #DB2C17;
text-decoration: none;
@@ -176,6 +188,28 @@ ul.nav li.logo a {
font-size: 20px;
color: #ddd;
}
+.listing .post.other .icon:hover {
+ text-decoration: none;
+ color: #bbb;
+}
+
+.listing blockquote {
+ border-left-color: #ddd;
+}
+
+@media only screen and (max-width: 520px) {
+ .listing .post {
+ margin: 30px 0;
+ }
+
+ .listing .post h2 {
+ font-size: 24px;
+ }
+
+ .listing .post .post-summary {
+ font-size: 18px;
+ }
+}
/*------------------------------------------------------------------------------
Post Styles
@@ -206,11 +240,18 @@ h1 {
font-size: 72px;
line-height: 0.8;
letter-spacing: -1px;
- color: #000;
+ color: #00000;
}
h1.words {
color: #DB2C17;
}
+h1.link {
+ font-size: 32px;
+}
+h1.link .desc {
+ font-weight: normal;
+ color: #000;
+}
@media only screen and (max-width: 700px) {
h1 {
font-size: 48px;
@@ -267,17 +308,14 @@ h4 {
}
blockquote {
- margin: 1em 0;
- padding: 0 35px;
- font-size: 14px;
- border: 1px dotted #ddd;
- border-left: none;
- border-right: none;
- background: url(../images/blockquote_open.gif) 0 12px no-repeat;
+ margin: 1.0em 0;
+ padding: 0 0 0 15px;
+ font-size: 16px;
+ border-left: 2px solid #aaa;
}
blockquote p {
margin: 12px 0;
- color: #666;
+ color: #999;
}
table {
@@ -293,7 +331,7 @@ table {
caption {
padding: 10px 10px 5px 0;
text-align: left;
- font-size: 11px;
+ font-size: 12px;
text-transform: uppercase;
font-weight: bold;
}
@@ -318,6 +356,22 @@ p.note {
color: #666;
}
+.twitter-tweet-rendered {
+ padding: 10px 0;
+}
+
+@media only screen and (max-width: 520px) {
+ h1 {
+ font-size: 30px;
+ line-height: 1.0;
+ letter-spacing: 0;
+ }
+
+ .container .twitter-tweet-rendered.tw-align-center {
+ width: 100% !important;
+ }
+}
+
/*----------------------------------------------------------------------------
Follow Box
----------------------------------------------------------------------------*/
@@ -336,6 +390,12 @@ p.note {
color: #666;
}
+@media only screen and (max-width: 520px) {
+ .keep-in-touch {
+ font-size: 14px;
+ }
+}
+
/*----------------------------------------------------------------------------
Code Styles
----------------------------------------------------------------------------*/
View
4 index.html
@@ -8,11 +8,13 @@
My name is Kyle Neath and I work at <a href="https://github.com">GitHub</a> in San Francisco. I love to build beautiful things with software and these are my words on design &amp; code.
</p>
+<hr />
+
<div class="listing">
{% for post in site.posts %}
{% if post.type == 'link' %}
<div class="post other link">
- <span class="icon" title="This is a link elsewhere">★</span>
+ <a class="icon" href="{{ post.url }}" title="This is a link elsewhere">★</a>
<h2><a href="{{ post.link }}">{{ post.title }}</a></h2>
<p>{{ post.content }}</p>
</div>
View
441 js/fastclick.js
@@ -0,0 +1,441 @@
+/**
+ * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
+ *
+ * @version 0.4.3
+ * @codingstandard ftlabs-jslint
+ * @copyright The Financial Times Limited [All Rights Reserved]
+ * @license MIT License (see LICENSE.txt)
+ */
+
+/*jslint browser:true, node:true*/
+/*global define*/
+
+
+/**
+ * Instantiate fast-clicking listeners on the specificed layer.
+ *
+ * @constructor
+ * @param {Element} layer The layer to listen on
+ */
+function FastClick(layer) {
+ 'use strict';
+ var oldOnClick, self = this;
+
+
+ /**
+ * Whether a click is currently being tracked.
+ *
+ * @type boolean
+ */
+ this.trackingClick = false;
+
+
+ /**
+ * Timestamp for when when click tracking started.
+ *
+ * @type number
+ */
+ this.trackingClickStart = 0;
+
+
+ /**
+ * The element being tracked for a click.
+ *
+ * @type Element
+ */
+ this.targetElement = null;
+
+
+ /**
+ * The FastClick layer.
+ *
+ * @type Element
+ */
+ this.layer = layer;
+
+ if (!layer || !layer.nodeType) {
+ throw new TypeError('Layer must be a document node');
+ }
+
+ // Bind handlers to this instance
+ this.onClick = function() { FastClick.prototype.onClick.apply(self, arguments); };
+ this.onTouchStart = function() { FastClick.prototype.onTouchStart.apply(self, arguments); };
+ this.onTouchMove = function() { FastClick.prototype.onTouchMove.apply(self, arguments); };
+ this.onTouchEnd = function() { FastClick.prototype.onTouchEnd.apply(self, arguments); };
+ this.onTouchCancel = function() { FastClick.prototype.onTouchCancel.apply(self, arguments); };
+
+ // Devices that don't support touch don't need FastClick
+ if (typeof window.ontouchstart === 'undefined') {
+ return;
+ }
+
+ // Set up event handlers as required
+ layer.addEventListener('click', this.onClick, true);
+ layer.addEventListener('touchstart', this.onTouchStart, false);
+ layer.addEventListener('touchmove', this.onTouchMove, false);
+ layer.addEventListener('touchend', this.onTouchEnd, false);
+ layer.addEventListener('touchcancel', this.onTouchCancel, false);
+
+ // If a handler is already declared in the element's onclick attribute, it will be fired before
+ // FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
+ // adding it as listener.
+ if (typeof layer.onclick === 'function') {
+
+ // Android browser on at least 3.2 requires a new reference to the function in layer.onclick
+ // - the old one won't work if passed to addEventListener directly.
+ oldOnClick = layer.onclick;
+ layer.addEventListener('click', function(event) {
+ oldOnClick(event);
+ }, false);
+ layer.onclick = null;
+ }
+}
+
+
+/**
+ * Android requires an exception for labels.
+ *
+ * @type boolean
+ */
+FastClick.prototype.deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0;
+
+
+/**
+ * Determine whether a given element requires a native click.
+ *
+ * @param {Element} target Target DOM element
+ * @returns {boolean} Returns true if the element needs a native click
+ */
+FastClick.prototype.needsClick = function(target) {
+ 'use strict';
+ switch (target.nodeName.toLowerCase()) {
+ case 'label':
+ case 'video':
+ return true;
+ default:
+ return (/\bneedsclick\b/).test(target.className);
+ }
+};
+
+
+/**
+ * Determine whether a given element requires a call to focus to simulate click into element.
+ *
+ * @param {Element} target Target DOM element
+ * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
+ */
+FastClick.prototype.needsFocus = function(target) {
+ 'use strict';
+ switch (target.nodeName.toLowerCase()) {
+ case 'textarea':
+ case 'select':
+ return true;
+ case 'input':
+ switch (target.type) {
+ case 'button':
+ case 'checkbox':
+ case 'file':
+ case 'image':
+ case 'radio':
+ case 'submit':
+ return false;
+ }
+ return true;
+ default:
+ return (/\bneedsfocus\b/).test(target.className);
+ }
+};
+
+
+/**
+ * Send a click event to the element if it needs it.
+ *
+ * @returns {boolean} Whether the click was sent or not
+ */
+FastClick.prototype.maybeSendClick = function(targetElement, event) {
+ 'use strict';
+ var clickEvent, touch;
+
+ // Prevent the actual click from going though - unless the target node is marked as requiring
+ // real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted
+ // to open the options list and so the original event is required.
+ if (this.needsClick(targetElement)) {
+ return false;
+ }
+
+ // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
+ if (document.activeElement && document.activeElement !== targetElement) {
+ document.activeElement.blur();
+ }
+
+ touch = event.changedTouches[0];
+
+ // Synthesise a click event, with an extra attribute so it can be tracked
+ clickEvent = document.createEvent('MouseEvents');
+ clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
+ clickEvent.forwardedTouchEvent = true;
+ targetElement.dispatchEvent(clickEvent);
+
+ return true;
+};
+
+
+/**
+ * On touch start, record the position and scroll offset.
+ *
+ * @param {Event} event
+ * @returns {boolean}
+ */
+FastClick.prototype.onTouchStart = function(event) {
+ 'use strict';
+ var touch = event.targetTouches[0];
+
+ this.trackingClick = true;
+ this.trackingClickStart = event.timeStamp;
+ this.targetElement = event.target;
+
+ this.touchStartX = touch.pageX;
+ this.touchStartY = touch.pageY;
+
+ if (event.timeStamp - this.lastClickTime < 200) {
+ event.preventDefault();
+ }
+ return true;
+};
+
+
+/**
+ * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
+ *
+ * @param {Event} event
+ * @returns {boolean}
+ */
+FastClick.prototype.touchHasMoved = function(event) {
+ 'use strict';
+ var touch = event.targetTouches[0];
+
+ if (Math.abs(touch.pageX - this.touchStartX) > 10 || Math.abs(touch.pageY - this.touchStartY) > 10) {
+ return true;
+ }
+
+ return false;
+};
+
+
+/**
+ * Update the last position.
+ *
+ * @param {Event} event
+ * @returns {boolean}
+ */
+FastClick.prototype.onTouchMove = function(event) {
+ 'use strict';
+ if (!this.trackingClick) {
+ return true;
+ }
+
+ // If the touch has moved, cancel the click tracking
+ if (this.targetElement !== event.target || this.touchHasMoved(event)) {
+ this.trackingClick = false;
+ this.targetElement = null;
+ }
+
+ return true;
+};
+
+
+/**
+ * Attempt to find the labelled control for the given label element.
+ *
+ * @param {HTMLLabelElement} labelElement
+ * @returns {HTMLInputElement|null}
+ */
+FastClick.prototype.findControl = function(labelElement) {
+ 'use strict';
+
+ // Fast path for newer browsers supporting the HTML5 control attribute
+ if (labelElement.control !== undefined) {
+ return labelElement.control;
+ }
+
+ // All browsers under test that support touch events also support the HTML5 htmlFor attribute
+ if (labelElement.htmlFor) {
+ return document.getElementById(labelElement.htmlFor);
+ }
+
+ // If no for attribute exists, attempt to retrieve the first labellable descendant element
+ // the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
+ return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
+};
+
+
+/**
+ * On touch end, determine whether to send a click event at once.
+ *
+ * @param {Event} event
+ * @returns {boolean}
+ */
+FastClick.prototype.onTouchEnd = function(event) {
+ 'use strict';
+ var forElement, trackingClickStart, targetElement = this.targetElement;
+
+ if (!this.trackingClick) {
+ return true;
+ }
+
+ if (event.timeStamp - this.lastClickTime < 200) {
+ this.cancelNextClick = true
+ return true;
+ }
+
+ this.lastClickTime = event.timeStamp
+
+ trackingClickStart = this.trackingClickStart;
+ this.trackingClick = false;
+ this.trackingClickStart = 0;
+
+ if (targetElement.nodeName.toLowerCase() === 'label') {
+ forElement = this.findControl(targetElement);
+ if (forElement) {
+ targetElement.focus();
+ if (this.deviceIsAndroid) {
+ return false;
+ }
+
+ if (this.maybeSendClick(forElement, event)) {
+ event.preventDefault();
+ }
+
+ return false;
+ }
+ } else if (this.needsFocus(targetElement)) {
+
+ // If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
+ if ((event.timeStamp - trackingClickStart) > 100) {
+
+ this.targetElement = null;
+ return true;
+ }
+
+ targetElement.focus();
+
+ // Select elements need the event to go through at least on iOS, otherwise the selector menu won't open.
+ if (targetElement.tagName.toLowerCase() !== 'select') {
+ event.preventDefault();
+ }
+
+ return false;
+ }
+
+ if (!this.maybeSendClick(targetElement, event)) {
+ return false;
+ }
+
+ event.preventDefault();
+ return false;
+};
+
+
+/**
+ * On touch cancel, stop tracking the click.
+ *
+ * @returns {void}
+ */
+FastClick.prototype.onTouchCancel = function() {
+ 'use strict';
+ this.trackingClick = false;
+ this.targetElement = null;
+};
+
+
+/**
+ * On actual clicks, determine whether this is a touch-generated click, a click action occurring
+ * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
+ * an actual click which should be permitted.
+ *
+ * @param {Event} event
+ * @returns {boolean}
+ */
+FastClick.prototype.onClick = function(event) {
+ 'use strict';
+
+ var oldTargetElement;
+
+ if (event.forwardedTouchEvent) {
+ return true;
+ }
+
+ // If a target element was never set (because a touch event was never fired) allow the click
+ if (!this.targetElement) {
+ return true;
+ }
+
+ oldTargetElement = this.targetElement;
+ this.targetElement = null;
+
+ // Programmatically generated events targeting a specific element should be permitted
+ if (!event.cancelable) {
+ return true;
+ }
+
+ // Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
+ if (event.target.type === 'submit' && event.detail === 0) {
+ return true;
+ }
+
+ // Derive and check the target element to see whether the click needs to be permitted;
+ // unless explicitly enabled, prevent non-touch click events from triggering actions,
+ // to prevent ghost/doubleclicks.
+ if (!this.needsClick(oldTargetElement) || this.cancelNextClick) {
+ this.cancelNextClick = false
+ // Prevent any user-added listeners declared on FastClick element from being fired.
+ if (event.stopImmediatePropagation) {
+ event.stopImmediatePropagation();
+ }
+
+ // Cancel the event
+ event.stopPropagation();
+ event.preventDefault();
+
+ return false;
+ }
+
+ // If clicks are permitted, return true for the action to go through.
+ return true;
+};
+
+
+/**
+ * Remove all FastClick's event listeners.
+ *
+ * @returns {void}
+ */
+FastClick.prototype.destroy = function() {
+ 'use strict';
+ var layer = this.layer;
+
+ layer.removeEventListener('click', this.onClick, true);
+ layer.removeEventListener('touchstart', this.onTouchStart, false);
+ layer.removeEventListener('touchmove', this.onTouchMove, false);
+ layer.removeEventListener('touchend', this.onTouchEnd, false);
+ layer.removeEventListener('touchcancel', this.onTouchCancel, false);
+};
+
+
+if (typeof define === 'function' && define.amd) {
+
+ // AMD. Register as an anonymous module.
+ define(function() {
+ 'use strict';
+ return FastClick;
+ });
+}
+
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = function(layer) {
+ 'use strict';
+ return new FastClick(layer);
+ };
+
+ module.exports.FastClick = FastClick;
+}

No commit comments for this range

Something went wrong with that request. Please try again.