{"action":"created","comment":{"url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments/77276097","id":77276097,"diff_hunk":"@@ -0,0 +1,307 @@\n+import React, { Component, PropTypes } from 'react';\n+import { connect } from 'react-redux';\n+import {\n+\tmap,\n+\tmax,\n+\tmin\n+} from 'lodash';\n+\n+// The following polyfills exist for the draft-js editor, since\n+// we are unable to change its codebase and yet we are waiting\n+// on a solid solution for general IE polyfills\n+//\n+// They were borrowed and modified from MDN\n+\n+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith\n+if ( ! String.prototype.endsWith ) {\n+\tString.prototype.endsWith = function( searchString, position ) {\n+\t\tconst subjectString = this.toString();\n+\t\tif (\n+\t\t\t( typeof position !== 'number' ) ||\n+\t\t\t( ! isFinite( position ) ) ||\n+\t\t\t( Math.floor( position ) !== position ) ||\n+\t\t\t( position > subjectString.length )\n+\t\t) {\n+\t\t\tposition = subjectString.length;\n+\t\t}\n+\t\tposition -= searchString.length;\n+\t\tconst lastIndex = subjectString.indexOf( searchString, position );\n+\t\treturn lastIndex !== -1 && lastIndex === position;\n+\t};\n+}\n+\n+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith\n+if ( ! String.prototype.startsWith ) {\n+\tString.prototype.startsWith = function( searchString, position ) {\n+\t\tposition = position || 0;\n+\t\treturn this.substr( position, searchString.length ) === searchString;\n+\t};\n+}\n+\n+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill\n+if ( ! Array.prototype.fill ) {\n+\tArray.prototype.fill = function( value ) {\n+\n+\t\t// Steps 1-2.\n+\t\tif ( this === null ) {\n+\t\t\tthrow new TypeError( 'this is null or not defined' );\n+\t\t}\n+\n+\t\tconst O = Object( this );\n+\n+\t\t// Steps 3-5.\n+\t\tconst len = O.length >>> 0;\n+\n+\t\t// Steps 6-7.\n+\t\tconst start = arguments[ 1 ];\n+\t\tconst relativeStart = start >> 0;\n+\n+\t\t// Step 8.\n+\t\tlet k = relativeStart < 0\n+\t\t\t? Math.max( len + relativeStart, 0 )\n+\t\t\t: Math.min( relativeStart, len );\n+\n+\t\t// Steps 9-10.\n+\t\tconst end = arguments[ 2 ];\n+\t\tconst relativeEnd = end === undefined\n+\t\t\t? len\n+\t\t\t: end >> 0;\n+\n+\t\t// Step 11.\n+\t\tconst final = relativeEnd < 0\n+\t\t\t? Math.max( len + relativeEnd, 0 )\n+\t\t\t: Math.min( relativeEnd, len );\n+\n+\t\t// Step 12.\n+\t\twhile ( k < final ) {\n+\t\t\tO[ k ] = value;\n+\t\t\tk++;\n+\t\t}\n+\n+\t\t// Step 13.\n+\t\treturn O;\n+\t};\n+}\n+\n+// The below is a `require()` statement becuase it needs to\n+// be loaded in after the polyfills are created.\n+const {\n+\tCompositeDecorator,\n+\tEditor,\n+\tEditorState,\n+\tEntity,\n+\tModifier,\n+\tSelectionState,\n+} = require( 'draft-js' );\n+\n+import Token from './token';\n+import { fromEditor, toEditor } from './parser';\n+import { buildSeoTitle } from 'state/sites/selectors';\n+import { getSelectedSite } from 'state/ui/selectors';\n+import { localize } from 'i18n-calypso';\n+\n+const Chip = onClick => props => <Token { ...props } onClick={ onClick } />;\n+\n+export class TitleFormatEditor extends Component {\n+\tconstructor( props ) {\n+\t\tsuper( props );\n+\n+\t\tthis.storeEditorReference = r => ( this.editor = r );\n+\t\tthis.focusEditor = () => this.editor.focus();\n+\n+\t\tthis.updateEditor = this.updateEditor.bind( this );\n+\t\tthis.addToken = this.addToken.bind( this );\n+\t\tthis.removeToken = this.removeToken.bind( this );\n+\t\tthis.renderTokens = this.renderTokens.bind( this );\n+\t\tthis.editorStateFrom = this.editorStateFrom.bind( this );\n+\n+\t\tthis.state = {\n+\t\t\teditorState: this.editorStateFrom( props ),\n+\t\t};\n+\t}\n+\n+\tcomponentWillReceiveProps( nextProps ) {\n+\t\tif ( this.props.disabled && ! nextProps.disabled ) {\n+\t\t\tthis.setState( {\n+\t\t\t\teditorState: this.editorStateFrom( nextProps )\n+\t\t\t} );\n+\t\t}\n+\t}\n+\n+\teditorStateFrom( props ) {\n+\t\treturn EditorState.createWithContent(\n+\t\t\ttoEditor( props.titleFormats, props.tokens ),\n+\t\t\tnew CompositeDecorator( [ {\n+\t\t\t\tstrategy: this.renderTokens,\n+\t\t\t\tcomponent: Chip( this.removeToken )\n+\t\t\t} ] )\n+\t\t);\n+\t}\n+\n+\tupdateEditor( editorState ) {\n+\t\tconst { onChange, type } = this.props;\n+\t\tconst currentContent = editorState.getCurrentContent();\n+\n+\t\t// limit to one line\n+\t\tif ( currentContent.getBlockMap().size > 1 ) {\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tthis.setState(\n+\t\t\t{ editorState },\n+\t\t\t() => {\n+\t\t\t\teditorState.lastChangeType === 'add-token' && this.focusEditor();\n+\t\t\t\tonChange( type.value, fromEditor( currentContent ) );\n+\t\t\t}\n+\t\t);\n+\t}\n+\n+\taddToken( title, name ) {\n+\t\treturn () => {\n+\t\t\tconst { editorState } = this.state;\n+\t\t\tconst currentSelection = editorState.getSelection();\n+\n+\t\t\tconst tokenEntity = Entity.create( 'TOKEN', 'IMMUTABLE', { name } );\n+\n+\t\t\tconst contentState = Modifier.replaceText(\n+\t\t\t\teditorState.getCurrentContent(),\n+\t\t\t\tcurrentSelection,\n+\t\t\t\ttitle,\n+\t\t\t\tnull,\n+\t\t\t\ttokenEntity\n+\t\t\t);\n+\n+\t\t\tthis.updateEditor( EditorState.push(\n+\t\t\t\teditorState,\n+\t\t\t\tcontentState,\n+\t\t\t\t'add-token'\n+\t\t\t) );\n+\t\t};\n+\t}\n+\n+\tremoveToken( entityKey ) {\n+\t\treturn () => {\n+\t\t\tconst { editorState } = this.state;\n+\t\t\tconst currentContent = editorState.getCurrentContent();\n+\t\t\tconst currentSelection = editorState.getSelection();\n+\n+\t\t\tconst block = currentContent.getBlockForKey( currentSelection.focusKey );\n+\n+\t\t\t// get characters in entity\n+\t\t\tconst indices = block\n+\t\t\t\t.getCharacterList()\n+\t\t\t\t.reduce( ( ids, value, key ) => {\n+\t\t\t\t\treturn entityKey === value.entity\n+\t\t\t\t\t\t? [ ...ids, key ]\n+\t\t\t\t\t\t: ids;\n+\t\t\t\t}, [] );\n+\n+\t\t\tconst range = SelectionState\n+\t\t\t\t.createEmpty( block.key )\n+\t\t\t\t.set( 'anchorOffset', min( indices ) )\n+\t\t\t\t.set( 'focusOffset', max( indices ) );\n+\n+\t\t\tconst withoutToken = EditorState.push(\n+\t\t\t\teditorState,\n+\t\t\t\tModifier.removeRange(\n+\t\t\t\t\tcurrentContent,\n+\t\t\t\t\trange,\n+\t\t\t\t\t'forward'\n+\t\t\t\t),\n+\t\t\t\t'remove-range'\n+\t\t\t);\n+\n+\t\t\tconst selectionBeforeToken = EditorState.forceSelection(\n+\t\t\t\twithoutToken,\n+\t\t\t\trange\n+\t\t\t\t\t.set( 'anchorOffset', min( indices ) )\n+\t\t\t\t\t.set( 'focusOffset', min( indices ) )\n+\t\t\t);\n+\n+\t\t\tthis.updateEditor( selectionBeforeToken );\n+\t\t};\n+\t}\n+\n+\trenderTokens( contentBlock, callback ) {\n+\t\tcontentBlock.findEntityRanges(\n+\t\t\tcharacter => {\n+\t\t\t\tconst entity = character.getEntity();\n+\n+\t\t\t\tif ( null === entity ) {\n+\t\t\t\t\treturn false;\n+\t\t\t\t}\n+\n+\t\t\t\treturn 'TOKEN' === Entity.get( entity ).getType();\n+\t\t\t},\n+\t\t\tcallback\n+\t\t);\n+\t}\n+\n+\trender() {\n+\t\tconst { editorState } = this.state;\n+\t\tconst {\n+\t\t\ttitleData,\n+\t\t\ttranslate,\n+\t\t\ttokens,\n+\t\t\ttype\n+\t\t} = this.props;\n+\n+\t\tconst previewText = type.value\n+\t\t\t? buildSeoTitle( { [ type.value ]: fromEditor( editorState.getCurrentContent() ) }, type.value, titleData )\n+\t\t\t: '';\n+\n+\t\tconst formattedPreview = previewText\n+\t\t\t? `${ translate( 'Preview' ) }: ${ previewText }`\n+\t\t\t: '';\n+\n+\t\treturn (\n+\t\t\t<div className=\"title-format-editor\">\n+\t\t\t\t<div className=\"title-format-editor__header\">\n+\t\t\t\t\t<span className=\"title-format-editor__title\">{ type.label }</span>\n+\t\t\t\t\t{ map( tokens, ( title, name ) => (\n+\t\t\t\t\t\t<span\n+\t\t\t\t\t\t\tkey={ name }\n+\t\t\t\t\t\t\tclassName=\"title-format-editor__button\"\n+\t\t\t\t\t\t\tonClick={ this.addToken( title, name ) }\n+\t\t\t\t\t\t>\n+\t\t\t\t\t\t\t{ title }\n+\t\t\t\t\t\t</span>\n+\t\t\t\t\t) ) }\n+\t\t\t\t</div>\n+\t\t\t\t<div className=\"title-format-editor__editor-wrapper\">\n+\t\t\t\t\t<Editor\n+\t\t\t\t\t\teditorState={ editorState }\n+\t\t\t\t\t\tonChange={ this.updateEditor }\n+\t\t\t\t\t\tref={ this.storeEditorReference }\n+\t\t\t\t\t/>\n+\t\t\t\t</div>\n+\t\t\t\t<div className=\"title-format-editor__preview\">{ formattedPreview }</div>\n+\t\t\t</div>\n+\t\t);\n+\t}\n+}\n+\n+TitleFormatEditor.displayName = 'TitleFormatEditor';","path":"client/components/title-format-editor/index.jsx","position":284,"original_position":284,"commit_id":"39b2a210ae05e4ebae9a0c6240019160cee2b8d2","original_commit_id":"39b2a210ae05e4ebae9a0c6240019160cee2b8d2","user":{"login":"gwwar","id":1270189,"avatar_url":"https://avatars.githubusercontent.com/u/1270189?v=3","gravatar_id":"","url":"https://api.github.com/users/gwwar","html_url":"https://github.com/gwwar","followers_url":"https://api.github.com/users/gwwar/followers","following_url":"https://api.github.com/users/gwwar/following{/other_user}","gists_url":"https://api.github.com/users/gwwar/gists{/gist_id}","starred_url":"https://api.github.com/users/gwwar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gwwar/subscriptions","organizations_url":"https://api.github.com/users/gwwar/orgs","repos_url":"https://api.github.com/users/gwwar/repos","events_url":"https://api.github.com/users/gwwar/events{/privacy}","received_events_url":"https://api.github.com/users/gwwar/received_events","type":"User","site_admin":false},"body":"I usually only expect these when we need a different name than the class name.","created_at":"2016-09-02T00:12:00Z","updated_at":"2016-09-02T00:12:00Z","html_url":"https://github.com/Automattic/wp-calypso/pull/7313#discussion_r77276097","pull_request_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313","_links":{"self":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments/77276097"},"html":{"href":"https://github.com/Automattic/wp-calypso/pull/7313#discussion_r77276097"},"pull_request":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313"}}},"pull_request":{"url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313","id":80318037,"html_url":"https://github.com/Automattic/wp-calypso/pull/7313","diff_url":"https://github.com/Automattic/wp-calypso/pull/7313.diff","patch_url":"https://github.com/Automattic/wp-calypso/pull/7313.patch","issue_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/7313","number":7313,"state":"open","locked":false,"title":"Introduce `draft.js` editor for custom title format","user":{"login":"dmsnell","id":5431237,"avatar_url":"https://avatars.githubusercontent.com/u/5431237?v=3","gravatar_id":"","url":"https://api.github.com/users/dmsnell","html_url":"https://github.com/dmsnell","followers_url":"https://api.github.com/users/dmsnell/followers","following_url":"https://api.github.com/users/dmsnell/following{/other_user}","gists_url":"https://api.github.com/users/dmsnell/gists{/gist_id}","starred_url":"https://api.github.com/users/dmsnell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmsnell/subscriptions","organizations_url":"https://api.github.com/users/dmsnell/orgs","repos_url":"https://api.github.com/users/dmsnell/repos","events_url":"https://api.github.com/users/dmsnell/events{/privacy}","received_events_url":"https://api.github.com/users/dmsnell/received_events","type":"User","site_admin":false},"body":"Central to resolving #7285 \r\n\r\nIn this PR we are introducing the `draft-js` rich editor as a way of improving the user experience when editing the custom title formats for their sites. Previously we were using the `<TokenField />` component as it was pre-built in Calypso and met most of our needs. Unfortunately, the extend to which our needs mapped onto that component hit a brick wall and the editing flow was very awkward. The goal for bringing in `draft-js` is to give us the right tool to make a custom rich-text entry without getting lost in the bugs and details required to make that happen across multiple browsers and millions of edge cases.\r\n\r\nThe new editor weighs in at around half a megabyte of code un-minified and un-compressed. To facilitate this without causing undue burden on the initial bundle download, we split the `settings/seo` panel into its own asynchronously loading JavaScript chunk. Minified and gzipped this appears to add a mere 66 KB to the app size. That is not a small overhead, but it's also not catastrophic for desktop and mobile users alike.\r\n\r\nThis PR is meant to be an example and an experiment to give us the opportunity to learn about the `draft-js` editor and gauge whether or not we feel like it would be worth replacing some existing editors (such as the TokenField) with this functional and structurally-backed model.\r\n\r\n**Before**\r\nThis is the version using `<TokenField />` for the title editing. It relies on typing a `,` in order to insert the token and once the token has been selected, it can't be used a second or third time. It's awkward to work with text around the tokens, and it's impossible (for underlying reasons) to type the text contents of those tokens without replacing the text _with_ the tokens.\r\n\r\n<img width=\"600\" alt=\"screen shot 2016-08-29 at 6 40 09 pm\" src=\"https://cloud.githubusercontent.com/assets/5431237/18073097/300c161c-6e18-11e6-9f15-20d9e465c20b.png\">\r\n\r\nWe could have split the editor out into separate sub panels as in the _after_ shot but didn't since we were working on this iteration. I don't have a video because something is broken right now in the existing development build (this should all be behind feature flags anyway)\r\n\r\n**After**\r\nThis is the new `draft-js`-based editor. The tokens can now be clicked on from a list to insert and from the title format itself to remove. They easily fit around arbitrary text and there is no need for special commands to work with them.\r\n\r\n![draft-title-editor](https://cloud.githubusercontent.com/assets/5431237/18073139/6f41a64e-6e18-11e6-9d64-cc2b8a07fe07.gif)\r\n\r\n## Testing\r\n\r\nNavigate to **My Sites** > **Settings** > **SEO** for a site with the business plan or above.\r\n\r\nTo test you will want to open a site with at least a business plan subscription. The editor should be gone for other sites, maybe a nudge will be in its place. Try and play with the title formats for your site. Try to break things.\r\n\r\n*For Reference*:\r\n - [draft.js data format](https://medium.com/@rajaraodv/how-draft-js-represents-rich-text-data-eeabb5f25cf2#.2jdmz2e59)\r\n - [API docs](https://facebook.github.io/draft-js/docs/overview.html#content)\r\n\r\ncc: @sirbrillig @roundhill @rodrigoi @aduth \r\n\r\nTest live: https://calypso.live/settings/seo?branch=experiment/draft-js-meta-title-editor","created_at":"2016-08-05T22:56:22Z","updated_at":"2016-09-02T00:12:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6672de19031d914f7299a0481808ffce42e82072","assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/Automattic/wp-calypso/milestones/96","html_url":"https://github.com/Automattic/wp-calypso/milestones/Advanced%20SEO","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/milestones/96/labels","id":1802510,"number":96,"title":"Advanced SEO","description":"Advanced SEO settings for the business plan.","creator":{"login":"roundhill","id":789137,"avatar_url":"https://avatars.githubusercontent.com/u/789137?v=3","gravatar_id":"","url":"https://api.github.com/users/roundhill","html_url":"https://github.com/roundhill","followers_url":"https://api.github.com/users/roundhill/followers","following_url":"https://api.github.com/users/roundhill/following{/other_user}","gists_url":"https://api.github.com/users/roundhill/gists{/gist_id}","starred_url":"https://api.github.com/users/roundhill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roundhill/subscriptions","organizations_url":"https://api.github.com/users/roundhill/orgs","repos_url":"https://api.github.com/users/roundhill/repos","events_url":"https://api.github.com/users/roundhill/events{/privacy}","received_events_url":"https://api.github.com/users/roundhill/received_events","type":"User","site_admin":false},"open_issues":5,"closed_issues":56,"state":"open","created_at":"2016-06-01T14:38:15Z","updated_at":"2016-09-01T15:02:17Z","due_on":"2016-08-15T00:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313/commits","review_comments_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313/comments","review_comment_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/7313/comments","statuses_url":"https://api.github.com/repos/Automattic/wp-calypso/statuses/39b2a210ae05e4ebae9a0c6240019160cee2b8d2","head":{"label":"Automattic:experiment/draft-js-meta-title-editor","ref":"experiment/draft-js-meta-title-editor","sha":"39b2a210ae05e4ebae9a0c6240019160cee2b8d2","user":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"repo":{"id":45936895,"name":"wp-calypso","full_name":"Automattic/wp-calypso","owner":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Automattic/wp-calypso","description":"The new JavaScript- and API-powered WordPress.com","fork":false,"url":"https://api.github.com/repos/Automattic/wp-calypso","forks_url":"https://api.github.com/repos/Automattic/wp-calypso/forks","keys_url":"https://api.github.com/repos/Automattic/wp-calypso/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Automattic/wp-calypso/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Automattic/wp-calypso/teams","hooks_url":"https://api.github.com/repos/Automattic/wp-calypso/hooks","issue_events_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/events{/number}","events_url":"https://api.github.com/repos/Automattic/wp-calypso/events","assignees_url":"https://api.github.com/repos/Automattic/wp-calypso/assignees{/user}","branches_url":"https://api.github.com/repos/Automattic/wp-calypso/branches{/branch}","tags_url":"https://api.github.com/repos/Automattic/wp-calypso/tags","blobs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Automattic/wp-calypso/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/refs{/sha}","trees_url":"https://api.github.com/repos/Automattic/wp-calypso/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Automattic/wp-calypso/statuses/{sha}","languages_url":"https://api.github.com/repos/Automattic/wp-calypso/languages","stargazers_url":"https://api.github.com/repos/Automattic/wp-calypso/stargazers","contributors_url":"https://api.github.com/repos/Automattic/wp-calypso/contributors","subscribers_url":"https://api.github.com/repos/Automattic/wp-calypso/subscribers","subscription_url":"https://api.github.com/repos/Automattic/wp-calypso/subscription","commits_url":"https://api.github.com/repos/Automattic/wp-calypso/commits{/sha}","git_commits_url":"https://api.github.com/repos/Automattic/wp-calypso/git/commits{/sha}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/comments{/number}","issue_comment_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/comments{/number}","contents_url":"https://api.github.com/repos/Automattic/wp-calypso/contents/{+path}","compare_url":"https://api.github.com/repos/Automattic/wp-calypso/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Automattic/wp-calypso/merges","archive_url":"https://api.github.com/repos/Automattic/wp-calypso/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Automattic/wp-calypso/downloads","issues_url":"https://api.github.com/repos/Automattic/wp-calypso/issues{/number}","pulls_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls{/number}","milestones_url":"https://api.github.com/repos/Automattic/wp-calypso/milestones{/number}","notifications_url":"https://api.github.com/repos/Automattic/wp-calypso/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/labels{/name}","releases_url":"https://api.github.com/repos/Automattic/wp-calypso/releases{/id}","deployments_url":"https://api.github.com/repos/Automattic/wp-calypso/deployments","created_at":"2015-11-10T20:00:16Z","updated_at":"2016-09-01T19:55:10Z","pushed_at":"2016-09-01T23:44:47Z","git_url":"git://github.com/Automattic/wp-calypso.git","ssh_url":"git@github.com:Automattic/wp-calypso.git","clone_url":"https://github.com/Automattic/wp-calypso.git","svn_url":"https://github.com/Automattic/wp-calypso","homepage":"https://developer.wordpress.com/calypso/","size":108414,"stargazers_count":7788,"watchers_count":7788,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":975,"mirror_url":null,"open_issues_count":1454,"forks":975,"open_issues":1454,"watchers":7788,"default_branch":"master"}},"base":{"label":"Automattic:master","ref":"master","sha":"587437b8e407901b110b7de3bb0aafb7dc59ef9e","user":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"repo":{"id":45936895,"name":"wp-calypso","full_name":"Automattic/wp-calypso","owner":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Automattic/wp-calypso","description":"The new JavaScript- and API-powered WordPress.com","fork":false,"url":"https://api.github.com/repos/Automattic/wp-calypso","forks_url":"https://api.github.com/repos/Automattic/wp-calypso/forks","keys_url":"https://api.github.com/repos/Automattic/wp-calypso/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Automattic/wp-calypso/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Automattic/wp-calypso/teams","hooks_url":"https://api.github.com/repos/Automattic/wp-calypso/hooks","issue_events_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/events{/number}","events_url":"https://api.github.com/repos/Automattic/wp-calypso/events","assignees_url":"https://api.github.com/repos/Automattic/wp-calypso/assignees{/user}","branches_url":"https://api.github.com/repos/Automattic/wp-calypso/branches{/branch}","tags_url":"https://api.github.com/repos/Automattic/wp-calypso/tags","blobs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Automattic/wp-calypso/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/refs{/sha}","trees_url":"https://api.github.com/repos/Automattic/wp-calypso/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Automattic/wp-calypso/statuses/{sha}","languages_url":"https://api.github.com/repos/Automattic/wp-calypso/languages","stargazers_url":"https://api.github.com/repos/Automattic/wp-calypso/stargazers","contributors_url":"https://api.github.com/repos/Automattic/wp-calypso/contributors","subscribers_url":"https://api.github.com/repos/Automattic/wp-calypso/subscribers","subscription_url":"https://api.github.com/repos/Automattic/wp-calypso/subscription","commits_url":"https://api.github.com/repos/Automattic/wp-calypso/commits{/sha}","git_commits_url":"https://api.github.com/repos/Automattic/wp-calypso/git/commits{/sha}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/comments{/number}","issue_comment_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/comments{/number}","contents_url":"https://api.github.com/repos/Automattic/wp-calypso/contents/{+path}","compare_url":"https://api.github.com/repos/Automattic/wp-calypso/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Automattic/wp-calypso/merges","archive_url":"https://api.github.com/repos/Automattic/wp-calypso/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Automattic/wp-calypso/downloads","issues_url":"https://api.github.com/repos/Automattic/wp-calypso/issues{/number}","pulls_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls{/number}","milestones_url":"https://api.github.com/repos/Automattic/wp-calypso/milestones{/number}","notifications_url":"https://api.github.com/repos/Automattic/wp-calypso/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/labels{/name}","releases_url":"https://api.github.com/repos/Automattic/wp-calypso/releases{/id}","deployments_url":"https://api.github.com/repos/Automattic/wp-calypso/deployments","created_at":"2015-11-10T20:00:16Z","updated_at":"2016-09-01T19:55:10Z","pushed_at":"2016-09-01T23:44:47Z","git_url":"git://github.com/Automattic/wp-calypso.git","ssh_url":"git@github.com:Automattic/wp-calypso.git","clone_url":"https://github.com/Automattic/wp-calypso.git","svn_url":"https://github.com/Automattic/wp-calypso","homepage":"https://developer.wordpress.com/calypso/","size":108414,"stargazers_count":7788,"watchers_count":7788,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":975,"mirror_url":null,"open_issues_count":1454,"forks":975,"open_issues":1454,"watchers":7788,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313"},"html":{"href":"https://github.com/Automattic/wp-calypso/pull/7313"},"issue":{"href":"https://api.github.com/repos/Automattic/wp-calypso/issues/7313"},"comments":{"href":"https://api.github.com/repos/Automattic/wp-calypso/issues/7313/comments"},"review_comments":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313/comments"},"review_comment":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/7313/commits"},"statuses":{"href":"https://api.github.com/repos/Automattic/wp-calypso/statuses/39b2a210ae05e4ebae9a0c6240019160cee2b8d2"}}}}
{"actor":{"display_login":"gwwar"}}