{"action":"created","comment":{"url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/comments/46084599","id":46084599,"diff_hunk":"@@ -0,0 +1,129 @@\n+/*\n+ *  Copyright (c) 2014-present, Facebook, Inc.\n+ *  All rights reserved.\n+ *\n+ *  This source code is licensed under the BSD-style license found in the\n+ *  LICENSE file in the root directory of this source tree. An additional grant\n+ *  of patent rights can be found in the PATENTS file in the same directory.\n+ *\n+ */\n+\n+#import <UIKit/UIKit.h>\n+\n+#ifndef ComponentKit_ASTextKitAttributes_h\n+#define ComponentKit_ASTextKitAttributes_h\n+\n+@protocol ASTextKitTruncating;\n+\n+extern NSString *const ASTextKitTruncationAttributeName;\n+/**\n+ Use ASTextKitEntityAttribute as the value of this attribute to embed a link or other interactable content inside the\n+ text.\n+ */\n+extern NSString *const ASTextKitEntityAttributeName;\n+\n+static inline BOOL _objectsEqual(id<NSObject> obj1, id<NSObject> obj2)\n+{\n+  return obj1 == obj2 ? YES : [obj1 isEqual:obj2];\n+}\n+\n+/**\n+ All NSObject values in this struct should be copied when passed into the TextComponent.\n+ */\n+struct ASTextKitAttributes {\n+  /**\n+   The string to be drawn.  ASTextKit will not augment this string with default colors, etc. so this must be complete.\n+   */\n+  NSAttributedString *attributedString;\n+  /**\n+   The string to use as the truncation string, usually just \"...\".  If you have a range of text you would like to\n+   restrict highlighting to (for instance if you have \"... Continue Reading\", use the ASTextKitTruncationAttributeName\n+   to mark the specific range of the string that should be highlightable.\n+   */\n+  NSAttributedString *truncationAttributedString;\n+  /**\n+   This is the character set that ASTextKit should attempt to avoid leaving as a trailing character before your\n+   truncation token.  By default this set includes \"\\s\\t\\n\\r.,!?:;\" so you don't end up with ugly looking truncation\n+   text like \"Hey, this is some fancy Truncation!\\n\\n...\".  Instead it would be truncated as \"Hey, this is some fancy\n+   truncation...\".  This is not always possible.\n+\n+   Set this to the empty charset if you want to just use the \"dumb\" truncation behavior.  A nil value will be\n+   substituted with the default described above.\n+   */\n+  NSCharacterSet *avoidTailTruncationSet;\n+  /**\n+   The line-break mode to apply to the text.  Since this also impacts how TextKit will attempt to truncate the text\n+   in your string, we only support NSLineBreakByWordWrapping and NSLineBreakByCharWrapping.\n+   */\n+  NSLineBreakMode lineBreakMode;\n+  /**\n+   The maximum number of lines to draw in the drawable region.  Leave blank or set to 0 to define no maximum.\n+   */\n+  NSUInteger maximumNumberOfLines;\n+  /**\n+   An array of UIBezierPath objects representing the exclusion paths inside the receiver's bounding rectangle. Default value: nil.\n+   */\n+  NSArray *exclusionPaths;\n+  /**\n+   The shadow offset for any shadows applied to the text.  The coordinate space for this is the same as UIKit, so a\n+   positive width means towards the right, and a positive height means towards the bottom.\n+   */\n+  CGSize shadowOffset;\n+  /**\n+   The color to use in drawing the text's shadow.\n+   */\n+  UIColor *shadowColor;\n+  /**\n+   The opacity of the shadow from 0 to 1.\n+   */\n+  CGFloat shadowOpacity;\n+  /**\n+   The radius that should be applied to the shadow blur.  Larger values mean a larger, more blurred shadow.\n+   */\n+  CGFloat shadowRadius;\n+  /**\n+   A pointer to a function that that returns a custom layout manager subclass. If nil, defaults to NSLayoutManager.\n+   */\n+  NSLayoutManager *(*layoutManagerFactory)(void);","path":"AsyncDisplayKit/TextKit/ASTextKitAttributes.h","position":87,"original_position":87,"commit_id":"6c2cfff11621bb0741e3a591f4b609850d450bde","original_commit_id":"6c2cfff11621bb0741e3a591f4b609850d450bde","user":{"login":"ocrickard","id":857665,"avatar_url":"https://avatars.githubusercontent.com/u/857665?v=3","gravatar_id":"","url":"https://api.github.com/users/ocrickard","html_url":"https://github.com/ocrickard","followers_url":"https://api.github.com/users/ocrickard/followers","following_url":"https://api.github.com/users/ocrickard/following{/other_user}","gists_url":"https://api.github.com/users/ocrickard/gists{/gist_id}","starred_url":"https://api.github.com/users/ocrickard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ocrickard/subscriptions","organizations_url":"https://api.github.com/users/ocrickard/orgs","repos_url":"https://api.github.com/users/ocrickard/repos","events_url":"https://api.github.com/users/ocrickard/events{/privacy}","received_events_url":"https://api.github.com/users/ocrickard/received_events","type":"User","site_admin":false},"body":"Yeah most likely you don't use this yet. We added this since the default answer on how to override something in TextKit is: subclass NSLayoutManager! ","created_at":"2015-11-28T21:29:11Z","updated_at":"2015-11-28T21:29:11Z","html_url":"https://github.com/facebook/AsyncDisplayKit/pull/825#discussion_r46084599","pull_request_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825","_links":{"self":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/comments/46084599"},"html":{"href":"https://github.com/facebook/AsyncDisplayKit/pull/825#discussion_r46084599"},"pull_request":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825"}}},"pull_request":{"url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825","id":50037831,"html_url":"https://github.com/facebook/AsyncDisplayKit/pull/825","diff_url":"https://github.com/facebook/AsyncDisplayKit/pull/825.diff","patch_url":"https://github.com/facebook/AsyncDisplayKit/pull/825.patch","issue_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/825","number":825,"state":"open","locked":false,"title":"Update ASTextNode renderer to latest ComponentKit implementation","user":{"login":"levi","id":8493,"avatar_url":"https://avatars.githubusercontent.com/u/8493?v=3","gravatar_id":"","url":"https://api.github.com/users/levi","html_url":"https://github.com/levi","followers_url":"https://api.github.com/users/levi/followers","following_url":"https://api.github.com/users/levi/following{/other_user}","gists_url":"https://api.github.com/users/levi/gists{/gist_id}","starred_url":"https://api.github.com/users/levi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/levi/subscriptions","organizations_url":"https://api.github.com/users/levi/orgs","repos_url":"https://api.github.com/users/levi/repos","events_url":"https://api.github.com/users/levi/events{/privacy}","received_events_url":"https://api.github.com/users/levi/received_events","type":"User","site_admin":false},"body":"I had some free time on a plane yesterday and saw this piece of low hanging fruit that didn't require much focus. I would like to contribute an ASLabelNode in the next couple of weeks and updating the backing renderer is a much needed addition before implementing methods like `minimumFontSize` and `adjustsFontSizeToFitWidth`.\r\n\r\nSome unit tests are failing right now, as it seems that the floating point math doesn't produce consistent results. @appleguy, you might have deeper insight into why this is. Going to dig a bit deeper into the TextKit sizing behavior to see what changed from the original implementation of ASTextNodeRenderer.\r\n\r\nThere were some API differences. I ended up adding an exclusionPaths attribute to the CKTextKitRenderer, which probably would make sense to contribute back to ComponentKit. `isTruncated` is reimplemented, as the truncation range is no longer exposed. And I ran into a build error when trying to include `ASTextKitRenderer.h` in the umbrella AsyncDisplayKit.h, as it seems to be trying to build the header as a C header and is confused where to find the `#import <vector>` c++ std lib header. I haven't worked much with Xcode's C++ integration, so help would be appreciated.\r\n\r\nI removed the legacy tests that were specific to the original renderer API. Naturally, I would like to bring up the tests to speed and need to decide a good testing strategy for this implementation. CK has a great suite of unit tests and there might be some value in copying them over to increase the coverage stats in the project. On the integration side, a snapshot test or two could be valuable, but need to identify possible areas of regression before spending too much time on creating test cases.\r\n\r\nResolves #804","created_at":"2015-11-07T15:10:17Z","updated_at":"2015-11-28T21:29:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"afeaa61b240718176daa58d76ffc996032883991","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825/commits","review_comments_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825/comments","review_comment_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/825/comments","statuses_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/statuses/6c2cfff11621bb0741e3a591f4b609850d450bde","head":{"label":"levi:levi/text-renderer","ref":"levi/text-renderer","sha":"6c2cfff11621bb0741e3a591f4b609850d450bde","user":{"login":"levi","id":8493,"avatar_url":"https://avatars.githubusercontent.com/u/8493?v=3","gravatar_id":"","url":"https://api.github.com/users/levi","html_url":"https://github.com/levi","followers_url":"https://api.github.com/users/levi/followers","following_url":"https://api.github.com/users/levi/following{/other_user}","gists_url":"https://api.github.com/users/levi/gists{/gist_id}","starred_url":"https://api.github.com/users/levi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/levi/subscriptions","organizations_url":"https://api.github.com/users/levi/orgs","repos_url":"https://api.github.com/users/levi/repos","events_url":"https://api.github.com/users/levi/events{/privacy}","received_events_url":"https://api.github.com/users/levi/received_events","type":"User","site_admin":false},"repo":{"id":35245356,"name":"AsyncDisplayKit","full_name":"levi/AsyncDisplayKit","owner":{"login":"levi","id":8493,"avatar_url":"https://avatars.githubusercontent.com/u/8493?v=3","gravatar_id":"","url":"https://api.github.com/users/levi","html_url":"https://github.com/levi","followers_url":"https://api.github.com/users/levi/followers","following_url":"https://api.github.com/users/levi/following{/other_user}","gists_url":"https://api.github.com/users/levi/gists{/gist_id}","starred_url":"https://api.github.com/users/levi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/levi/subscriptions","organizations_url":"https://api.github.com/users/levi/orgs","repos_url":"https://api.github.com/users/levi/repos","events_url":"https://api.github.com/users/levi/events{/privacy}","received_events_url":"https://api.github.com/users/levi/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/levi/AsyncDisplayKit","description":"Smooth asynchronous user interfaces for iOS apps.","fork":true,"url":"https://api.github.com/repos/levi/AsyncDisplayKit","forks_url":"https://api.github.com/repos/levi/AsyncDisplayKit/forks","keys_url":"https://api.github.com/repos/levi/AsyncDisplayKit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/levi/AsyncDisplayKit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/levi/AsyncDisplayKit/teams","hooks_url":"https://api.github.com/repos/levi/AsyncDisplayKit/hooks","issue_events_url":"https://api.github.com/repos/levi/AsyncDisplayKit/issues/events{/number}","events_url":"https://api.github.com/repos/levi/AsyncDisplayKit/events","assignees_url":"https://api.github.com/repos/levi/AsyncDisplayKit/assignees{/user}","branches_url":"https://api.github.com/repos/levi/AsyncDisplayKit/branches{/branch}","tags_url":"https://api.github.com/repos/levi/AsyncDisplayKit/tags","blobs_url":"https://api.github.com/repos/levi/AsyncDisplayKit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/levi/AsyncDisplayKit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/levi/AsyncDisplayKit/git/refs{/sha}","trees_url":"https://api.github.com/repos/levi/AsyncDisplayKit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/levi/AsyncDisplayKit/statuses/{sha}","languages_url":"https://api.github.com/repos/levi/AsyncDisplayKit/languages","stargazers_url":"https://api.github.com/repos/levi/AsyncDisplayKit/stargazers","contributors_url":"https://api.github.com/repos/levi/AsyncDisplayKit/contributors","subscribers_url":"https://api.github.com/repos/levi/AsyncDisplayKit/subscribers","subscription_url":"https://api.github.com/repos/levi/AsyncDisplayKit/subscription","commits_url":"https://api.github.com/repos/levi/AsyncDisplayKit/commits{/sha}","git_commits_url":"https://api.github.com/repos/levi/AsyncDisplayKit/git/commits{/sha}","comments_url":"https://api.github.com/repos/levi/AsyncDisplayKit/comments{/number}","issue_comment_url":"https://api.github.com/repos/levi/AsyncDisplayKit/issues/comments{/number}","contents_url":"https://api.github.com/repos/levi/AsyncDisplayKit/contents/{+path}","compare_url":"https://api.github.com/repos/levi/AsyncDisplayKit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/levi/AsyncDisplayKit/merges","archive_url":"https://api.github.com/repos/levi/AsyncDisplayKit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/levi/AsyncDisplayKit/downloads","issues_url":"https://api.github.com/repos/levi/AsyncDisplayKit/issues{/number}","pulls_url":"https://api.github.com/repos/levi/AsyncDisplayKit/pulls{/number}","milestones_url":"https://api.github.com/repos/levi/AsyncDisplayKit/milestones{/number}","notifications_url":"https://api.github.com/repos/levi/AsyncDisplayKit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/levi/AsyncDisplayKit/labels{/name}","releases_url":"https://api.github.com/repos/levi/AsyncDisplayKit/releases{/id}","created_at":"2015-05-07T21:50:39Z","updated_at":"2015-05-08T04:58:49Z","pushed_at":"2015-11-28T02:59:14Z","git_url":"git://github.com/levi/AsyncDisplayKit.git","ssh_url":"git@github.com:levi/AsyncDisplayKit.git","clone_url":"https://github.com/levi/AsyncDisplayKit.git","svn_url":"https://github.com/levi/AsyncDisplayKit","homepage":"http://asyncdisplaykit.org","size":10972,"stargazers_count":0,"watchers_count":0,"language":"Objective-C","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"supplementary-views"}},"base":{"label":"facebook:master","ref":"master","sha":"59d52ced3fbae5fc0e6220eabd692602062bb2c1","user":{"login":"facebook","id":69631,"avatar_url":"https://avatars.githubusercontent.com/u/69631?v=3","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"repo":{"id":21265042,"name":"AsyncDisplayKit","full_name":"facebook/AsyncDisplayKit","owner":{"login":"facebook","id":69631,"avatar_url":"https://avatars.githubusercontent.com/u/69631?v=3","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/facebook/AsyncDisplayKit","description":"Smooth asynchronous user interfaces for iOS apps.","fork":false,"url":"https://api.github.com/repos/facebook/AsyncDisplayKit","forks_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/forks","keys_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/teams","hooks_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/hooks","issue_events_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/events{/number}","events_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/events","assignees_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/assignees{/user}","branches_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/branches{/branch}","tags_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/tags","blobs_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/git/refs{/sha}","trees_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/statuses/{sha}","languages_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/languages","stargazers_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/stargazers","contributors_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/contributors","subscribers_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/subscribers","subscription_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/subscription","commits_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/commits{/sha}","git_commits_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/git/commits{/sha}","comments_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/comments{/number}","issue_comment_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/comments{/number}","contents_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/contents/{+path}","compare_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/merges","archive_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/downloads","issues_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues{/number}","pulls_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls{/number}","milestones_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/milestones{/number}","notifications_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/labels{/name}","releases_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/releases{/id}","created_at":"2014-06-27T05:29:02Z","updated_at":"2015-11-28T19:44:10Z","pushed_at":"2015-11-28T02:59:16Z","git_url":"git://github.com/facebook/AsyncDisplayKit.git","ssh_url":"git@github.com:facebook/AsyncDisplayKit.git","clone_url":"https://github.com/facebook/AsyncDisplayKit.git","svn_url":"https://github.com/facebook/AsyncDisplayKit","homepage":"http://asyncdisplaykit.org","size":10901,"stargazers_count":6391,"watchers_count":6391,"language":"Objective-C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":927,"mirror_url":null,"open_issues_count":138,"forks":927,"open_issues":138,"watchers":6391,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825"},"html":{"href":"https://github.com/facebook/AsyncDisplayKit/pull/825"},"issue":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/825"},"comments":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/825/comments"},"review_comments":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825/comments"},"review_comment":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/825/commits"},"statuses":{"href":"https://api.github.com/repos/facebook/AsyncDisplayKit/statuses/6c2cfff11621bb0741e3a591f4b609850d450bde"}}}}