{"action":"created","comment":{"url":"https://api.github.com/repos/uberfire/uberfire/pulls/comments/71522244","id":71522244,"diff_hunk":"@@ -0,0 +1,317 @@\n+/*\n+ * Copyright 2016 Red Hat, Inc. and/or its affiliates.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *       http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+package org.uberfire.ext.wires.core.grids.client.widget.grid.impl;\n+\n+import java.util.List;\n+\n+import com.ait.lienzo.client.core.shape.Viewport;\n+import com.ait.lienzo.client.core.types.Point2D;\n+import com.ait.lienzo.client.core.types.Transform;\n+import com.google.gwt.event.dom.client.KeyCodes;\n+import com.google.gwt.event.dom.client.KeyDownEvent;\n+import com.google.gwt.event.dom.client.KeyDownHandler;\n+import org.uberfire.commons.validation.PortablePreconditions;\n+import org.uberfire.ext.wires.core.grids.client.model.Bounds;\n+import org.uberfire.ext.wires.core.grids.client.model.GridColumn;\n+import org.uberfire.ext.wires.core.grids.client.model.GridData;\n+import org.uberfire.ext.wires.core.grids.client.model.GridRow;\n+import org.uberfire.ext.wires.core.grids.client.util.ColumnIndexUtilities;\n+import org.uberfire.ext.wires.core.grids.client.widget.dom.single.HasSingletonDOMElementResource;\n+import org.uberfire.ext.wires.core.grids.client.widget.grid.GridWidget;\n+import org.uberfire.ext.wires.core.grids.client.widget.grid.renderers.grids.GridRenderer;\n+import org.uberfire.ext.wires.core.grids.client.widget.grid.renderers.grids.impl.BaseGridRendererHelper;\n+import org.uberfire.ext.wires.core.grids.client.widget.grid.selections.CellSelectionManager;\n+import org.uberfire.ext.wires.core.grids.client.widget.layer.GridLayer;\n+\n+/**\n+ * KeyDownHandler for keyboard operations. Keyboard operations supported:\n+ * <ul>\n+ * <li>Clearing cell content with the DELETE key</li>\n+ * <li>Edit a cell content with the ENTER key</li>\n+ * <li>Keyboard navigation with the CURSOR keys</li>\n+ * <li>Move to top-left cell with HOME key</li>\n+ * <li>Move to bottom-right cell with END key</li>\n+ * </ul>\n+ * All operations keep the selection origin in view, i.e. the @{link Viewport} is\n+ * translated to keep the cell in view if necessary.\n+ */\n+public class BaseGridWidgetKeyboardHandler implements KeyDownHandler {\n+\n+    protected GridLayer gridLayer;\n+\n+    public BaseGridWidgetKeyboardHandler( final GridLayer gridLayer ) {\n+        this.gridLayer = PortablePreconditions.checkNotNull( \"gridLayer\",\n+                                                             gridLayer );\n+    }\n+\n+    @Override\n+    public void onKeyDown( final KeyDownEvent event ) {\n+        final GridWidget selectedGridWidget = getSelectedGridWidget();\n+        if ( selectedGridWidget == null ) {\n+            return;\n+        }\n+\n+        boolean handled = false;\n+        boolean renderLayer = false;\n+        final int nativeKeyCode = event.getNativeKeyCode();\n+\n+        if ( nativeKeyCode == KeyCodes.KEY_DELETE ) {\n+            handled = true;\n+            renderLayer = true;\n+            clearCells();\n+\n+        } else if ( nativeKeyCode == KeyCodes.KEY_ENTER ) {\n+            handled = true;\n+            editCell();\n+\n+        } else if ( nativeKeyCode == KeyCodes.KEY_HOME ) {\n+            handled = true;\n+            renderLayer = selectTopLeftCell();\n+            scrollSelectedCellIntoView();\n+\n+        } else if ( nativeKeyCode == KeyCodes.KEY_END ) {\n+            handled = true;\n+            renderLayer = selectBottomRightCell();\n+            scrollSelectedCellIntoView();\n+\n+        } else if ( event.isLeftArrow() ) {\n+            handled = true;\n+            renderLayer = adjustSelection( CellSelectionManager.SelectionExtensionDirection.LEFT,\n+                                           event.isShiftKeyDown() );\n+            scrollSelectedCellIntoView();\n+\n+        } else if ( event.isRightArrow() ) {\n+            handled = true;\n+            renderLayer = adjustSelection( CellSelectionManager.SelectionExtensionDirection.RIGHT,\n+                                           event.isShiftKeyDown() );\n+            scrollSelectedCellIntoView();\n+\n+        } else if ( event.isUpArrow() ) {\n+            handled = true;\n+            renderLayer = adjustSelection( CellSelectionManager.SelectionExtensionDirection.UP,\n+                                           event.isShiftKeyDown() );\n+            scrollSelectedCellIntoView();\n+\n+        } else if ( event.isDownArrow() ) {\n+            handled = true;\n+            renderLayer = adjustSelection( CellSelectionManager.SelectionExtensionDirection.DOWN,\n+                                           event.isShiftKeyDown() );\n+            scrollSelectedCellIntoView();\n+        }\n+\n+        if ( handled ) {\n+            event.preventDefault();\n+            event.stopPropagation();\n+\n+            final GridData gridModel = selectedGridWidget.getModel();\n+            for ( GridColumn<?> column : gridModel.getColumns() ) {\n+                if ( column instanceof HasSingletonDOMElementResource ) {\n+                    ( (HasSingletonDOMElementResource) column ).flush();\n+                    ( (HasSingletonDOMElementResource) column ).destroyResources();\n+                }\n+            }\n+\n+            if ( renderLayer ) {\n+                gridLayer.draw();\n+            }\n+        }\n+    }\n+\n+    protected void clearCells() {\n+        final GridWidget selectedGridWidget = getSelectedGridWidget();\n+        if ( selectedGridWidget == null ) {\n+            return;\n+        }\n+        final GridData gridModel = selectedGridWidget.getModel();\n+        final List<GridData.SelectedCell> selectedCells = gridModel.getSelectedCells();\n+        for ( GridData.SelectedCell cell : selectedCells ) {\n+            gridModel.deleteCell( cell.getRowIndex(),\n+                                  cell.getColumnIndex() );\n+        }\n+    }\n+\n+    protected void editCell() {\n+        final GridWidget selectedGridWidget = getSelectedGridWidget();\n+        if ( selectedGridWidget == null ) {\n+            return;\n+        }\n+        final GridData gridModel = selectedGridWidget.getModel();\n+        final GridData.SelectedCell origin = gridModel.getSelectedCellsOrigin();\n+        if ( origin == null ) {\n+            return;\n+        }\n+        selectedGridWidget.startEditingCell( origin.getRowIndex(),\n+                                             ColumnIndexUtilities.findUiColumnIndex( gridModel.getColumns(),\n+                                                                                     origin.getColumnIndex() ) );\n+    }\n+\n+    protected boolean adjustSelection( final CellSelectionManager.SelectionExtensionDirection direction,\n+                                       final boolean isShiftKeyDown ) {\n+        final GridWidget selectedGridWidget = getSelectedGridWidget();\n+        if ( selectedGridWidget == null ) {\n+            return false;\n+        }\n+        return selectedGridWidget.adjustSelection( direction,\n+                                                   isShiftKeyDown );\n+    }\n+\n+    protected boolean selectTopLeftCell() {\n+        final GridWidget selectedGridWidget = getSelectedGridWidget();\n+        if ( selectedGridWidget == null ) {\n+            return false;\n+        }\n+        final GridData gridModel = selectedGridWidget.getModel();\n+        final int rowCount = gridModel.getRowCount();\n+        final int columnCount = gridModel.getColumnCount();\n+        if ( rowCount == 0 || columnCount == 0 ) {\n+            return false;\n+        }\n+        return selectedGridWidget.selectCell( 0,\n+                                              0,\n+                                              false,\n+                                              false );\n+    }\n+\n+    protected boolean selectBottomRightCell() {\n+        final GridWidget selectedGridWidget = getSelectedGridWidget();\n+        if ( selectedGridWidget == null ) {\n+            return false;\n+        }\n+        final GridData gridModel = selectedGridWidget.getModel();\n+        final int rowCount = gridModel.getRowCount();\n+        final int columnCount = gridModel.getColumnCount();\n+        if ( rowCount == 0 || columnCount == 0 ) {\n+            return false;\n+        }\n+        return selectedGridWidget.selectCell( rowCount - 1,\n+                                              columnCount - 1,\n+                                              false,\n+                                              false );\n+    }\n+\n+    boolean scrollSelectedCellIntoView() {\n+        final GridWidget selectedGridWidget = getSelectedGridWidget();\n+        if ( selectedGridWidget == null ) {\n+            return false;\n+        }\n+        final GridData gridModel = selectedGridWidget.getModel();\n+        final List<GridData.SelectedCell> selectedCells = gridModel.getSelectedCells();\n+        if ( selectedCells == null ) {\n+            return false;\n+        }\n+        if ( selectedCells.size() != 1 ) {\n+            return false;\n+        }\n+\n+        final double dx = getCellScrollDeltaX( selectedGridWidget );\n+        final double dy = getCellScrollDeltaY( selectedGridWidget );\n+\n+        if ( dx != 0 || dy != 0 ) {\n+            adjustViewportTransform( gridLayer.getViewport(),\n+                                     new Point2D( dx,\n+                                                  dy ) );\n+        }\n+        return true;\n+    }\n+\n+    private double getCellScrollDeltaX( final GridWidget gridWidget ) {\n+        final GridData gridModel = gridWidget.getModel();\n+        final GridData.SelectedCell origin = gridModel.getSelectedCellsOrigin();\n+        final BaseGridRendererHelper rendererHelper = gridWidget.getRendererHelper();\n+        final BaseGridRendererHelper.RenderingInformation renderingInformation = rendererHelper.getRenderingInformation();\n+        if ( renderingInformation == null ) {\n+            return 0.0;\n+        }\n+\n+        final BaseGridRendererHelper.RenderingBlockInformation floatingBlockInformation = renderingInformation.getFloatingBlockInformation();\n+        final int uiColumnIndex = ColumnIndexUtilities.findUiColumnIndex( gridModel.getColumns(),\n+                                                                          origin.getColumnIndex() );\n+\n+        final List<GridColumn<?>> columns = gridModel.getColumns();\n+        final GridColumn<?> column = columns.get( uiColumnIndex );\n+        final List<GridColumn<?>> floatingColumns = floatingBlockInformation.getColumns();\n+\n+        if ( floatingColumns.contains( column ) ) {\n+            return 0.0;\n+        }\n+\n+        final int columnIndex = columns.indexOf( column );\n+        final double cellMinX = rendererHelper.getColumnOffset( columns,\n+                                                                columnIndex );\n+        final double gridCellX = gridWidget.getX() + cellMinX;\n+\n+        double dx = 0;\n+        final Bounds bounds = gridLayer.getVisibleBounds();\n+        if ( gridCellX + column.getWidth() >= bounds.getX() + bounds.getWidth() ) {\n+            dx = bounds.getX() + bounds.getWidth() - gridCellX - column.getWidth();\n+        } else if ( gridCellX <= bounds.getX() ) {\n+            dx = bounds.getX() - gridCellX;\n+        }\n+\n+        return dx;\n+    }\n+\n+    private double getCellScrollDeltaY( final GridWidget gridWidget ) {\n+        final GridData gridModel = gridWidget.getModel();","path":"uberfire-extensions/uberfire-wires/uberfire-wires-core/uberfire-wires-core-grids/src/main/java/org/uberfire/ext/wires/core/grids/client/widget/grid/impl/BaseGridWidgetKeyboardHandler.java","position":268,"original_position":268,"commit_id":"ced81f3928786cf6c9536488ecbf6197877a6bda","original_commit_id":"ced81f3928786cf6c9536488ecbf6197877a6bda","user":{"login":"ederign","id":531351,"avatar_url":"https://avatars.githubusercontent.com/u/531351?v=3","gravatar_id":"","url":"https://api.github.com/users/ederign","html_url":"https://github.com/ederign","followers_url":"https://api.github.com/users/ederign/followers","following_url":"https://api.github.com/users/ederign/following{/other_user}","gists_url":"https://api.github.com/users/ederign/gists{/gist_id}","starred_url":"https://api.github.com/users/ederign/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ederign/subscriptions","organizations_url":"https://api.github.com/users/ederign/orgs","repos_url":"https://api.github.com/users/ederign/repos","events_url":"https://api.github.com/users/ederign/events{/privacy}","received_events_url":"https://api.github.com/users/ederign/received_events","type":"User","site_admin":false},"body":"same as above","created_at":"2016-07-20T13:20:40Z","updated_at":"2016-07-20T13:20:40Z","html_url":"https://github.com/uberfire/uberfire/pull/445#discussion_r71522244","pull_request_url":"https://api.github.com/repos/uberfire/uberfire/pulls/445","_links":{"self":{"href":"https://api.github.com/repos/uberfire/uberfire/pulls/comments/71522244"},"html":{"href":"https://github.com/uberfire/uberfire/pull/445#discussion_r71522244"},"pull_request":{"href":"https://api.github.com/repos/uberfire/uberfire/pulls/445"}}},"pull_request":{"url":"https://api.github.com/repos/uberfire/uberfire/pulls/445","id":78129617,"html_url":"https://github.com/uberfire/uberfire/pull/445","diff_url":"https://github.com/uberfire/uberfire/pull/445.diff","patch_url":"https://github.com/uberfire/uberfire/pull/445.patch","issue_url":"https://api.github.com/repos/uberfire/uberfire/issues/445","number":445,"state":"open","locked":false,"title":"GUVNOR-2557: Add keyboard navigation through the table","user":{"login":"manstis","id":497544,"avatar_url":"https://avatars.githubusercontent.com/u/497544?v=3","gravatar_id":"","url":"https://api.github.com/users/manstis","html_url":"https://github.com/manstis","followers_url":"https://api.github.com/users/manstis/followers","following_url":"https://api.github.com/users/manstis/following{/other_user}","gists_url":"https://api.github.com/users/manstis/gists{/gist_id}","starred_url":"https://api.github.com/users/manstis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/manstis/subscriptions","organizations_url":"https://api.github.com/users/manstis/orgs","repos_url":"https://api.github.com/users/manstis/repos","events_url":"https://api.github.com/users/manstis/events{/privacy}","received_events_url":"https://api.github.com/users/manstis/received_events","type":"User","site_admin":false},"body":"See https://issues.jboss.org/browse/GUVNOR-2557","created_at":"2016-07-20T11:19:23Z","updated_at":"2016-07-20T13:20:41Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7770545a160060323f85f2821239cdf69afcb46a","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/uberfire/uberfire/pulls/445/commits","review_comments_url":"https://api.github.com/repos/uberfire/uberfire/pulls/445/comments","review_comment_url":"https://api.github.com/repos/uberfire/uberfire/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uberfire/uberfire/issues/445/comments","statuses_url":"https://api.github.com/repos/uberfire/uberfire/statuses/ced81f3928786cf6c9536488ecbf6197877a6bda","head":{"label":"manstis:GUVNOR-2557","ref":"GUVNOR-2557","sha":"ced81f3928786cf6c9536488ecbf6197877a6bda","user":{"login":"manstis","id":497544,"avatar_url":"https://avatars.githubusercontent.com/u/497544?v=3","gravatar_id":"","url":"https://api.github.com/users/manstis","html_url":"https://github.com/manstis","followers_url":"https://api.github.com/users/manstis/followers","following_url":"https://api.github.com/users/manstis/following{/other_user}","gists_url":"https://api.github.com/users/manstis/gists{/gist_id}","starred_url":"https://api.github.com/users/manstis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/manstis/subscriptions","organizations_url":"https://api.github.com/users/manstis/orgs","repos_url":"https://api.github.com/users/manstis/repos","events_url":"https://api.github.com/users/manstis/events{/privacy}","received_events_url":"https://api.github.com/users/manstis/received_events","type":"User","site_admin":false},"repo":{"id":35973354,"name":"uberfire","full_name":"manstis/uberfire","owner":{"login":"manstis","id":497544,"avatar_url":"https://avatars.githubusercontent.com/u/497544?v=3","gravatar_id":"","url":"https://api.github.com/users/manstis","html_url":"https://github.com/manstis","followers_url":"https://api.github.com/users/manstis/followers","following_url":"https://api.github.com/users/manstis/following{/other_user}","gists_url":"https://api.github.com/users/manstis/gists{/gist_id}","starred_url":"https://api.github.com/users/manstis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/manstis/subscriptions","organizations_url":"https://api.github.com/users/manstis/orgs","repos_url":"https://api.github.com/users/manstis/repos","events_url":"https://api.github.com/users/manstis/events{/privacy}","received_events_url":"https://api.github.com/users/manstis/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/manstis/uberfire","description":"UberFire Framework","fork":true,"url":"https://api.github.com/repos/manstis/uberfire","forks_url":"https://api.github.com/repos/manstis/uberfire/forks","keys_url":"https://api.github.com/repos/manstis/uberfire/keys{/key_id}","collaborators_url":"https://api.github.com/repos/manstis/uberfire/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/manstis/uberfire/teams","hooks_url":"https://api.github.com/repos/manstis/uberfire/hooks","issue_events_url":"https://api.github.com/repos/manstis/uberfire/issues/events{/number}","events_url":"https://api.github.com/repos/manstis/uberfire/events","assignees_url":"https://api.github.com/repos/manstis/uberfire/assignees{/user}","branches_url":"https://api.github.com/repos/manstis/uberfire/branches{/branch}","tags_url":"https://api.github.com/repos/manstis/uberfire/tags","blobs_url":"https://api.github.com/repos/manstis/uberfire/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/manstis/uberfire/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/manstis/uberfire/git/refs{/sha}","trees_url":"https://api.github.com/repos/manstis/uberfire/git/trees{/sha}","statuses_url":"https://api.github.com/repos/manstis/uberfire/statuses/{sha}","languages_url":"https://api.github.com/repos/manstis/uberfire/languages","stargazers_url":"https://api.github.com/repos/manstis/uberfire/stargazers","contributors_url":"https://api.github.com/repos/manstis/uberfire/contributors","subscribers_url":"https://api.github.com/repos/manstis/uberfire/subscribers","subscription_url":"https://api.github.com/repos/manstis/uberfire/subscription","commits_url":"https://api.github.com/repos/manstis/uberfire/commits{/sha}","git_commits_url":"https://api.github.com/repos/manstis/uberfire/git/commits{/sha}","comments_url":"https://api.github.com/repos/manstis/uberfire/comments{/number}","issue_comment_url":"https://api.github.com/repos/manstis/uberfire/issues/comments{/number}","contents_url":"https://api.github.com/repos/manstis/uberfire/contents/{+path}","compare_url":"https://api.github.com/repos/manstis/uberfire/compare/{base}...{head}","merges_url":"https://api.github.com/repos/manstis/uberfire/merges","archive_url":"https://api.github.com/repos/manstis/uberfire/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/manstis/uberfire/downloads","issues_url":"https://api.github.com/repos/manstis/uberfire/issues{/number}","pulls_url":"https://api.github.com/repos/manstis/uberfire/pulls{/number}","milestones_url":"https://api.github.com/repos/manstis/uberfire/milestones{/number}","notifications_url":"https://api.github.com/repos/manstis/uberfire/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/manstis/uberfire/labels{/name}","releases_url":"https://api.github.com/repos/manstis/uberfire/releases{/id}","deployments_url":"https://api.github.com/repos/manstis/uberfire/deployments","created_at":"2015-05-20T20:46:56Z","updated_at":"2016-01-11T09:21:01Z","pushed_at":"2016-07-20T11:15:52Z","git_url":"git://github.com/manstis/uberfire.git","ssh_url":"git@github.com:manstis/uberfire.git","clone_url":"https://github.com/manstis/uberfire.git","svn_url":"https://github.com/manstis/uberfire","homepage":"http://www.uberfireframework.org","size":38055,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"uberfire:master","ref":"master","sha":"f224e11d8eb69fa0e6df3c59b79cede72fe592cc","user":{"login":"uberfire","id":5167699,"avatar_url":"https://avatars.githubusercontent.com/u/5167699?v=3","gravatar_id":"","url":"https://api.github.com/users/uberfire","html_url":"https://github.com/uberfire","followers_url":"https://api.github.com/users/uberfire/followers","following_url":"https://api.github.com/users/uberfire/following{/other_user}","gists_url":"https://api.github.com/users/uberfire/gists{/gist_id}","starred_url":"https://api.github.com/users/uberfire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uberfire/subscriptions","organizations_url":"https://api.github.com/users/uberfire/orgs","repos_url":"https://api.github.com/users/uberfire/repos","events_url":"https://api.github.com/users/uberfire/events{/privacy}","received_events_url":"https://api.github.com/users/uberfire/received_events","type":"Organization","site_admin":false},"repo":{"id":4335576,"name":"uberfire","full_name":"uberfire/uberfire","owner":{"login":"uberfire","id":5167699,"avatar_url":"https://avatars.githubusercontent.com/u/5167699?v=3","gravatar_id":"","url":"https://api.github.com/users/uberfire","html_url":"https://github.com/uberfire","followers_url":"https://api.github.com/users/uberfire/followers","following_url":"https://api.github.com/users/uberfire/following{/other_user}","gists_url":"https://api.github.com/users/uberfire/gists{/gist_id}","starred_url":"https://api.github.com/users/uberfire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uberfire/subscriptions","organizations_url":"https://api.github.com/users/uberfire/orgs","repos_url":"https://api.github.com/users/uberfire/repos","events_url":"https://api.github.com/users/uberfire/events{/privacy}","received_events_url":"https://api.github.com/users/uberfire/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uberfire/uberfire","description":"UberFire Framework","fork":false,"url":"https://api.github.com/repos/uberfire/uberfire","forks_url":"https://api.github.com/repos/uberfire/uberfire/forks","keys_url":"https://api.github.com/repos/uberfire/uberfire/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uberfire/uberfire/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uberfire/uberfire/teams","hooks_url":"https://api.github.com/repos/uberfire/uberfire/hooks","issue_events_url":"https://api.github.com/repos/uberfire/uberfire/issues/events{/number}","events_url":"https://api.github.com/repos/uberfire/uberfire/events","assignees_url":"https://api.github.com/repos/uberfire/uberfire/assignees{/user}","branches_url":"https://api.github.com/repos/uberfire/uberfire/branches{/branch}","tags_url":"https://api.github.com/repos/uberfire/uberfire/tags","blobs_url":"https://api.github.com/repos/uberfire/uberfire/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uberfire/uberfire/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uberfire/uberfire/git/refs{/sha}","trees_url":"https://api.github.com/repos/uberfire/uberfire/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uberfire/uberfire/statuses/{sha}","languages_url":"https://api.github.com/repos/uberfire/uberfire/languages","stargazers_url":"https://api.github.com/repos/uberfire/uberfire/stargazers","contributors_url":"https://api.github.com/repos/uberfire/uberfire/contributors","subscribers_url":"https://api.github.com/repos/uberfire/uberfire/subscribers","subscription_url":"https://api.github.com/repos/uberfire/uberfire/subscription","commits_url":"https://api.github.com/repos/uberfire/uberfire/commits{/sha}","git_commits_url":"https://api.github.com/repos/uberfire/uberfire/git/commits{/sha}","comments_url":"https://api.github.com/repos/uberfire/uberfire/comments{/number}","issue_comment_url":"https://api.github.com/repos/uberfire/uberfire/issues/comments{/number}","contents_url":"https://api.github.com/repos/uberfire/uberfire/contents/{+path}","compare_url":"https://api.github.com/repos/uberfire/uberfire/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uberfire/uberfire/merges","archive_url":"https://api.github.com/repos/uberfire/uberfire/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uberfire/uberfire/downloads","issues_url":"https://api.github.com/repos/uberfire/uberfire/issues{/number}","pulls_url":"https://api.github.com/repos/uberfire/uberfire/pulls{/number}","milestones_url":"https://api.github.com/repos/uberfire/uberfire/milestones{/number}","notifications_url":"https://api.github.com/repos/uberfire/uberfire/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uberfire/uberfire/labels{/name}","releases_url":"https://api.github.com/repos/uberfire/uberfire/releases{/id}","deployments_url":"https://api.github.com/repos/uberfire/uberfire/deployments","created_at":"2012-05-15T12:40:55Z","updated_at":"2016-07-07T21:19:58Z","pushed_at":"2016-07-20T11:19:23Z","git_url":"git://github.com/uberfire/uberfire.git","ssh_url":"git@github.com:uberfire/uberfire.git","clone_url":"https://github.com/uberfire/uberfire.git","svn_url":"https://github.com/uberfire/uberfire","homepage":"http://www.uberfireframework.org","size":41831,"stargazers_count":61,"watchers_count":61,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":96,"mirror_url":null,"open_issues_count":4,"forks":96,"open_issues":4,"watchers":61,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/uberfire/uberfire/pulls/445"},"html":{"href":"https://github.com/uberfire/uberfire/pull/445"},"issue":{"href":"https://api.github.com/repos/uberfire/uberfire/issues/445"},"comments":{"href":"https://api.github.com/repos/uberfire/uberfire/issues/445/comments"},"review_comments":{"href":"https://api.github.com/repos/uberfire/uberfire/pulls/445/comments"},"review_comment":{"href":"https://api.github.com/repos/uberfire/uberfire/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uberfire/uberfire/pulls/445/commits"},"statuses":{"href":"https://api.github.com/repos/uberfire/uberfire/statuses/ced81f3928786cf6c9536488ecbf6197877a6bda"}}}}
{"actor":{"display_login":"ederign"}}