From 3921e417eeea5f20216799196b27ce83dc8edec9 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Fri, 20 Nov 2015 08:31:53 -0800 Subject: [PATCH 01/22] Fixed django connection or list field. Fixed #43 --- graphene/contrib/django/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene/contrib/django/fields.py b/graphene/contrib/django/fields.py index 62d376d7..c64b9547 100644 --- a/graphene/contrib/django/fields.py +++ b/graphene/contrib/django/fields.py @@ -34,7 +34,7 @@ class ConnectionOrListField(Field): field = DjangoConnectionField(field_object_type) else: field = LazyListField(field_object_type) - field.contribute_to_class(self.object_type, self.name) + field.contribute_to_class(self.object_type, self.attname) return schema.T(field) From 732b1aec1ba65bca8d57f3ce78794e67f564dc67 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Fri, 20 Nov 2015 16:12:11 -0800 Subject: [PATCH 02/22] Update Connections --- graphene/contrib/django/fields.py | 4 +--- graphene/contrib/django/types.py | 13 +++++++++++-- graphene/core/types/objecttype.py | 4 ++++ graphene/relay/fields.py | 22 +++------------------- graphene/relay/types.py | 12 ++++++++++++ 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/graphene/contrib/django/fields.py b/graphene/contrib/django/fields.py index c64b9547..0b719586 100644 --- a/graphene/contrib/django/fields.py +++ b/graphene/contrib/django/fields.py @@ -8,9 +8,7 @@ from .utils import get_type_for_model, lazy_map class DjangoConnectionField(ConnectionField): - - def wrap_resolved(self, value, instance, args, info): - return lazy_map(value, self.type) + pass class LazyListField(Field): diff --git a/graphene/contrib/django/types.py b/graphene/contrib/django/types.py index f17893f0..8ef2a6a3 100644 --- a/graphene/contrib/django/types.py +++ b/graphene/contrib/django/types.py @@ -2,10 +2,10 @@ import six from ...core.types import BaseObjectType, ObjectTypeMeta from ...relay.fields import GlobalIDField -from ...relay.types import BaseNode +from ...relay.types import BaseNode, Connection from .converter import convert_django_field from .options import DjangoOptions -from .utils import get_reverse_fields +from .utils import get_reverse_fields, lazy_map class DjangoObjectTypeMeta(ObjectTypeMeta): @@ -71,6 +71,13 @@ class DjangoInterface(six.with_metaclass( pass +class DjangoConnection(Connection): + @classmethod + def from_list(cls, iterable, *args, **kwargs): + iterable = lazy_map(iterable, cls.edge_type.node_type) + return super(DjangoConnection, cls).from_list(iterable, *args, **kwargs) + + class DjangoNode(BaseNode, DjangoInterface): id = GlobalIDField() @@ -81,3 +88,5 @@ class DjangoNode(BaseNode, DjangoInterface): return cls(instance) except cls._meta.model.DoesNotExist: return None + + connection_type = DjangoConnection diff --git a/graphene/core/types/objecttype.py b/graphene/core/types/objecttype.py index e18518e9..14283af5 100644 --- a/graphene/core/types/objecttype.py +++ b/graphene/core/types/objecttype.py @@ -219,6 +219,10 @@ class BaseObjectType(BaseType): return OrderedDict(fields) + @classmethod + def wrap(cls, instance, args, info): + return cls(_root=instance) + class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)): pass diff --git a/graphene/relay/fields.py b/graphene/relay/fields.py index 58e0e8bd..a54140ee 100644 --- a/graphene/relay/fields.py +++ b/graphene/relay/fields.py @@ -1,6 +1,3 @@ -from collections import Iterable - -from graphql_relay.connection.arrayconnection import connection_from_list from graphql_relay.node.node import from_global_id from ..core.fields import Field @@ -30,24 +27,11 @@ class ConnectionField(Field): return value def resolver(self, instance, args, info): - from graphene.relay.types import PageInfo schema = info.schema.graphene_schema - + connection_type = self.get_type(schema) resolved = super(ConnectionField, self).resolver(instance, args, info) - if resolved: - resolved = self.wrap_resolved(resolved, instance, args, info) - assert isinstance( - resolved, Iterable), 'Resolved value from the connection field have to be iterable' - type = schema.T(self.type) - node = schema.objecttype(type) - connection_type = self.get_connection_type(node) - edge_type = self.get_edge_type(node) - - connection = connection_from_list( - resolved, args, connection_type=connection_type, - edge_type=edge_type, pageinfo_type=PageInfo) - connection.set_connection_data(resolved) - return connection + if not isinstance(resolved, connection_type): + return connection_type.from_list(resolved, args, info) def get_connection_type(self, node): connection_type = self.connection_type or node.get_connection_type() diff --git a/graphene/relay/types.py b/graphene/relay/types.py index a803d2f3..3969a09e 100644 --- a/graphene/relay/types.py +++ b/graphene/relay/types.py @@ -1,6 +1,8 @@ import inspect import warnings +from collections import Iterable from functools import wraps +from graphql_relay.connection.arrayconnection import connection_from_list from graphql_relay.node.node import to_global_id from ..core.types import (Boolean, Field, InputObjectType, Interface, List, @@ -63,6 +65,16 @@ class Connection(ObjectType): (cls,), {'edge_type': edge_type, 'edges': edges}) + @classmethod + def from_list(cls, iterable, args, info): + assert isinstance( + iterable, Iterable), 'Resolved value from the connection field have to be iterable' + connection = connection_from_list( + iterable, args, connection_type=cls, + edge_type=cls.edge_type, pageinfo_type=PageInfo) + connection.set_connection_data(iterable) + return connection + def set_connection_data(self, data): self._connection_data = data From c521e181c8da49017d0f5074267d81fe95247a8c Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 21 Nov 2015 10:51:49 -0800 Subject: [PATCH 03/22] Simplified Django grapheme types removing LazyMap --- graphene/contrib/django/fields.py | 22 ++++++++++------------ graphene/contrib/django/types.py | 6 +++--- graphene/contrib/django/utils.py | 7 +------ 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/graphene/contrib/django/fields.py b/graphene/contrib/django/fields.py index 0b719586..7b990b86 100644 --- a/graphene/contrib/django/fields.py +++ b/graphene/contrib/django/fields.py @@ -1,24 +1,22 @@ +import warnings + from ...core.exceptions import SkipField from ...core.fields import Field from ...core.types.base import FieldType from ...core.types.definitions import List from ...relay import ConnectionField from ...relay.utils import is_node -from .utils import get_type_for_model, lazy_map +from .utils import get_type_for_model class DjangoConnectionField(ConnectionField): - pass - -class LazyListField(Field): - - def get_type(self, schema): - return List(self.type) - - def resolver(self, instance, args, info): - resolved = super(LazyListField, self).resolver(instance, args, info) - return lazy_map(resolved, self.type) + def __init__(self, *args, **kwargs): + cls = self.__class__ + warnings.warn("Using {} will be not longer supported." + " Use relay.ConnectionField instead".format(cls.__name__), + FutureWarning) + return super(DjangoConnectionField, self).__init__(*args, **kwargs) class ConnectionOrListField(Field): @@ -31,7 +29,7 @@ class ConnectionOrListField(Field): if is_node(field_object_type): field = DjangoConnectionField(field_object_type) else: - field = LazyListField(field_object_type) + field = Field(List(field_object_type)) field.contribute_to_class(self.object_type, self.attname) return schema.T(field) diff --git a/graphene/contrib/django/types.py b/graphene/contrib/django/types.py index 8ef2a6a3..55b76fa7 100644 --- a/graphene/contrib/django/types.py +++ b/graphene/contrib/django/types.py @@ -5,7 +5,7 @@ from ...relay.fields import GlobalIDField from ...relay.types import BaseNode, Connection from .converter import convert_django_field from .options import DjangoOptions -from .utils import get_reverse_fields, lazy_map +from .utils import get_reverse_fields, maybe_queryset class DjangoObjectTypeMeta(ObjectTypeMeta): @@ -30,7 +30,7 @@ class DjangoObjectTypeMeta(ObjectTypeMeta): is_excluded = field.name in cls._meta.exclude_fields or is_already_created if is_not_in_only or is_excluded: # We skip this field if we specify only_fields and is not - # in there. Or when we excldue this field in exclude_fields + # in there. Or when we exclude this field in exclude_fields continue converted_field = convert_django_field(field) cls.add_to_class(field.name, converted_field) @@ -74,7 +74,7 @@ class DjangoInterface(six.with_metaclass( class DjangoConnection(Connection): @classmethod def from_list(cls, iterable, *args, **kwargs): - iterable = lazy_map(iterable, cls.edge_type.node_type) + iterable = maybe_queryset(iterable) return super(DjangoConnection, cls).from_list(iterable, *args, **kwargs) diff --git a/graphene/contrib/django/utils.py b/graphene/contrib/django/utils.py index 0d557e9a..54c6420c 100644 --- a/graphene/contrib/django/utils.py +++ b/graphene/contrib/django/utils.py @@ -1,8 +1,5 @@ from django.db import models from django.db.models.manager import Manager -from django.db.models.query import QuerySet - -from ...utils import LazyMap def get_type_for_model(schema, model): @@ -22,9 +19,7 @@ def get_reverse_fields(model): yield related -def lazy_map(value, func): +def maybe_queryset(value): if isinstance(value, Manager): value = value.get_queryset() - if isinstance(value, QuerySet): - return LazyMap(value, func) return value From 137ba498682a1b559f0e746da2a503f6add37eb4 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 21 Nov 2015 10:58:49 -0800 Subject: [PATCH 04/22] Removed LazyMap --- graphene/utils/__init__.py | 3 +- graphene/utils/lazymap.py | 43 ---------------------------- graphene/utils/tests/test_lazymap.py | 23 --------------- 3 files changed, 1 insertion(+), 68 deletions(-) delete mode 100644 graphene/utils/lazymap.py delete mode 100644 graphene/utils/tests/test_lazymap.py diff --git a/graphene/utils/__init__.py b/graphene/utils/__init__.py index bb1a2150..52fb6417 100644 --- a/graphene/utils/__init__.py +++ b/graphene/utils/__init__.py @@ -1,11 +1,10 @@ from .str_converters import to_camel_case, to_snake_case from .proxy_snake_dict import ProxySnakeDict from .caching import cached_property, memoize -from .lazymap import LazyMap from .misc import enum_to_graphql_enum from .resolve_only_args import resolve_only_args __all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict', - 'cached_property', 'memoize', 'LazyMap', 'enum_to_graphql_enum', + 'cached_property', 'memoize', 'enum_to_graphql_enum', 'resolve_only_args'] diff --git a/graphene/utils/lazymap.py b/graphene/utils/lazymap.py deleted file mode 100644 index 236f91eb..00000000 --- a/graphene/utils/lazymap.py +++ /dev/null @@ -1,43 +0,0 @@ -class LazyMap(object): - - def __init__(self, origin, _map, state=None): - self._origin = origin - self._origin_iter = origin.__iter__() - self._state = state or [] - self._finished = False - self._map = _map - - def __iter__(self): - return self if not self._finished else iter(self._state) - - def iter(self): - return self.__iter__() - - def __len__(self): - return self._origin.__len__() - - def __next__(self): - try: - n = next(self._origin_iter) - n = self._map(n) - except StopIteration as e: - self._finished = True - raise e - else: - self._state.append(n) - return n - - def next(self): - return self.__next__() - - def __getitem__(self, key): - item = self._origin[key] - if isinstance(key, slice): - return LazyMap(item, self._map) - return self._map(item) - - def __getattr__(self, name): - return getattr(self._origin, name) - - def __repr__(self): - return "" % repr(self._origin) diff --git a/graphene/utils/tests/test_lazymap.py b/graphene/utils/tests/test_lazymap.py deleted file mode 100644 index e6ee1f36..00000000 --- a/graphene/utils/tests/test_lazymap.py +++ /dev/null @@ -1,23 +0,0 @@ -from py.test import raises - -from ..lazymap import LazyMap - - -def test_lazymap(): - data = list(range(10)) - lm = LazyMap(data, lambda x: 2 * x) - assert len(lm) == 10 - assert lm[1] == 2 - assert isinstance(lm[1:4], LazyMap) - assert lm.append == data.append - assert repr(lm) == '' - - -def test_lazymap_iter(): - data = list(range(2)) - lm = LazyMap(data, lambda x: 2 * x) - iter_lm = iter(lm) - assert iter_lm.next() == 0 - assert iter_lm.next() == 2 - with raises(StopIteration): - iter_lm.next() From 79c7d070db664c864a74b7f4d2faa13cfb8472c8 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 21 Nov 2015 18:16:31 -0800 Subject: [PATCH 05/22] Fixed isort --- graphene/contrib/django/types.py | 1 + graphene/relay/types.py | 1 + setup.cfg | 3 +++ 3 files changed, 5 insertions(+) diff --git a/graphene/contrib/django/types.py b/graphene/contrib/django/types.py index 55b76fa7..b5097c72 100644 --- a/graphene/contrib/django/types.py +++ b/graphene/contrib/django/types.py @@ -72,6 +72,7 @@ class DjangoInterface(six.with_metaclass( class DjangoConnection(Connection): + @classmethod def from_list(cls, iterable, *args, **kwargs): iterable = maybe_queryset(iterable) diff --git a/graphene/relay/types.py b/graphene/relay/types.py index 3969a09e..9fa673ef 100644 --- a/graphene/relay/types.py +++ b/graphene/relay/types.py @@ -2,6 +2,7 @@ import inspect import warnings from collections import Iterable from functools import wraps + from graphql_relay.connection.arrayconnection import connection_from_list from graphql_relay.node.node import to_global_id diff --git a/setup.cfg b/setup.cfg index 11382a78..21db934b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,3 +4,6 @@ max-line-length = 120 [coverage:run] omit = core/ntypes/tests/* + +[isort] +known_first_party=graphene From c28b0466061bd91d3cba0b4814eea0d2df508414 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 21 Nov 2015 19:04:58 -0800 Subject: [PATCH 06/22] Added DjangoConnection to the public --- graphene/contrib/django/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graphene/contrib/django/__init__.py b/graphene/contrib/django/__init__.py index ca89906a..ec39b7f9 100644 --- a/graphene/contrib/django/__init__.py +++ b/graphene/contrib/django/__init__.py @@ -1,4 +1,5 @@ from graphene.contrib.django.types import ( + DjangoConnection, DjangoObjectType, DjangoInterface, DjangoNode @@ -9,4 +10,4 @@ from graphene.contrib.django.fields import ( ) __all__ = ['DjangoObjectType', 'DjangoInterface', 'DjangoNode', - 'DjangoConnectionField', 'DjangoModelField'] + 'DjangoConnection', 'DjangoConnectionField', 'DjangoModelField'] From 36ab537bf28e4164dba663f5b1540eb12e25f5f2 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 21 Nov 2015 19:14:45 -0800 Subject: [PATCH 07/22] Updated to version 0.4.2 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 100e2321..4be1ad98 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ class PyTest(TestCommand): setup( name='graphene', - version='0.4.1.1', + version='0.4.2', description='Graphene: Python DSL for GraphQL', long_description=open('README.rst').read(), From fe860774e8525cb50095f857c6013cffbc41f117 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sun, 22 Nov 2015 16:04:14 -0800 Subject: [PATCH 08/22] Fixed return ConnectionType instance in ConnectionField resolver --- graphene/relay/fields.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/graphene/relay/fields.py b/graphene/relay/fields.py index a54140ee..b3829ad8 100644 --- a/graphene/relay/fields.py +++ b/graphene/relay/fields.py @@ -30,8 +30,9 @@ class ConnectionField(Field): schema = info.schema.graphene_schema connection_type = self.get_type(schema) resolved = super(ConnectionField, self).resolver(instance, args, info) - if not isinstance(resolved, connection_type): - return connection_type.from_list(resolved, args, info) + if isinstance(resolved, connection_type): + return resolved + return connection_type.from_list(resolved, args, info) def get_connection_type(self, node): connection_type = self.connection_type or node.get_connection_type() From b564e144dfea7c28047ae609de4af72b7d984ffd Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sun, 22 Nov 2015 17:29:30 -0800 Subject: [PATCH 09/22] Improved examples. Fixed #45 --- examples/complex_example.py | 31 +++++++++++++++++++ .../{field_example.py => simple_example.py} | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 examples/complex_example.py rename examples/{field_example.py => simple_example.py} (98%) diff --git a/examples/complex_example.py b/examples/complex_example.py new file mode 100644 index 00000000..dd801fff --- /dev/null +++ b/examples/complex_example.py @@ -0,0 +1,31 @@ +import graphene + + +class GeoInput(graphene.InputObjectType): + lat = graphene.Float(required=True) + lng = graphene.Float(required=True) + + +class Address(graphene.ObjectType): + latlng = graphene.String() + + +class Query(graphene.ObjectType): + address = graphene.Field(Address, geo=graphene.Argument(GeoInput)) + + def resolve_address(self, args, info): + geo = args.get('geo') + return Address(latlng="({},{})".format(geo.get('lat'), geo.get('lng'))) + + +schema = graphene.Schema(query=Query) +query = ''' + query something{ + address(geo: {lat:32.2, lng:12}) { + latlng + } + } +''' + +result = schema.execute(query) +print(result.data['address']['latlng']) diff --git a/examples/field_example.py b/examples/simple_example.py similarity index 98% rename from examples/field_example.py rename to examples/simple_example.py index be41969d..bc4b9d34 100644 --- a/examples/field_example.py +++ b/examples/simple_example.py @@ -21,7 +21,7 @@ query = ''' id name } -} + } ''' result = schema.execute(query) print(result.data['patron']) From a0d8b7162abd27e544f8de1eb2501e76e0e2b77a Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Tue, 24 Nov 2015 23:57:27 -0800 Subject: [PATCH 10/22] Remove blinker dependency --- graphene/signals.py | 7 ++++++- setup.py | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/graphene/signals.py b/graphene/signals.py index ccb9ef0f..cdfa3d06 100644 --- a/graphene/signals.py +++ b/graphene/signals.py @@ -1,4 +1,9 @@ -from blinker import Signal +try: + from blinker import Signal +except ImportError: + class Signal(object): + def send(self, *args, **kwargs): + pass init_schema = Signal() class_prepared = Signal() diff --git a/setup.py b/setup.py index 4be1ad98..e8c61433 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,6 @@ setup( install_requires=[ 'six>=1.10.0', - 'blinker', 'graphql-core==0.4.9', 'graphql-relay==0.3.3' ], From 7340d80fa64d4aa815300322de5a9c5b25c394c3 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 25 Nov 2015 11:33:32 -0800 Subject: [PATCH 11/22] Changed type resolver function name to _resolve_type. Fixed #50 --- graphene/contrib/django/tests/test_types.py | 2 +- graphene/core/tests/test_query.py | 5 ++++- graphene/core/types/objecttype.py | 4 ++-- graphene/core/types/tests/test_objecttype.py | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/graphene/contrib/django/tests/test_types.py b/graphene/contrib/django/tests/test_types.py index 5d7f582e..4d709580 100644 --- a/graphene/contrib/django/tests/test_types.py +++ b/graphene/contrib/django/tests/test_types.py @@ -69,7 +69,7 @@ def test_node_replacedfield(): def test_interface_resolve_type(): - resolve_type = Character.resolve_type(schema, Human()) + resolve_type = Character._resolve_type(schema, Human()) assert isinstance(resolve_type, GraphQLObjectType) diff --git a/graphene/core/tests/test_query.py b/graphene/core/tests/test_query.py index b9e8ee84..5fbe2faa 100644 --- a/graphene/core/tests/test_query.py +++ b/graphene/core/tests/test_query.py @@ -13,7 +13,10 @@ class Character(Interface): class Pet(ObjectType): - type = String(resolver=lambda *_: 'Dog') + type = String() + + def resolve_type(self, args, info): + return 'Dog' class Human(Character): diff --git a/graphene/core/types/objecttype.py b/graphene/core/types/objecttype.py index 14283af5..09f65ad0 100644 --- a/graphene/core/types/objecttype.py +++ b/graphene/core/types/objecttype.py @@ -182,7 +182,7 @@ class BaseObjectType(BaseType): signals.post_init.send(self.__class__, instance=self) @classmethod - def resolve_type(cls, schema, instance, *args): + def _resolve_type(cls, schema, instance, *args): return schema.T(instance.__class__) @classmethod @@ -191,7 +191,7 @@ class BaseObjectType(BaseType): return GraphQLInterfaceType( cls._meta.type_name, description=cls._meta.description, - resolve_type=partial(cls.resolve_type, schema), + resolve_type=partial(cls._resolve_type, schema), fields=partial(cls.get_fields, schema) ) elif cls._meta.is_union: diff --git a/graphene/core/types/tests/test_objecttype.py b/graphene/core/types/tests/test_objecttype.py index add37bae..6bb157d6 100644 --- a/graphene/core/types/tests/test_objecttype.py +++ b/graphene/core/types/tests/test_objecttype.py @@ -75,7 +75,7 @@ def test_union_cannot_initialize(): def test_interface_resolve_type(): - resolve_type = Character.resolve_type(schema, Human(object())) + resolve_type = Character._resolve_type(schema, Human(object())) assert isinstance(resolve_type, GraphQLObjectType) From 059f25c44cda7a8afe33179262ba1ab0a2d4a32c Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Thu, 26 Nov 2015 23:50:37 -0800 Subject: [PATCH 12/22] First version docs playground --- docs/css/graphiql.css | 1070 ++++++++++++++++++++++++++++++++++ docs/css/main.styl | 11 +- docs/css/playground.styl | 38 ++ docs/gatsby.config.js | 23 +- docs/package.json | 3 + docs/pages/_empty.js | 9 + docs/pages/_template.js | 4 +- docs/pages/docs/_template.js | 2 +- docs/pages/playground.js | 1 + docs/playground/page.js | 67 +++ docs/playground/schema.js | 59 ++ docs/playground/wrapper.js | 22 + docs/wrappers/md.js | 2 +- 13 files changed, 1301 insertions(+), 10 deletions(-) create mode 100644 docs/css/graphiql.css create mode 100644 docs/css/playground.styl create mode 100644 docs/pages/_empty.js create mode 100644 docs/pages/playground.js create mode 100644 docs/playground/page.js create mode 100644 docs/playground/schema.js create mode 100644 docs/playground/wrapper.js diff --git a/docs/css/graphiql.css b/docs/css/graphiql.css new file mode 100644 index 00000000..c8af1081 --- /dev/null +++ b/docs/css/graphiql.css @@ -0,0 +1,1070 @@ +#graphiql-container { + color: #141823; + width: 100%; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + height: 100%; + font-family: system, -apple-system, 'San Francisco', '.SFNSDisplay-Regular', 'Segoe UI', Segoe, 'Segoe WP', 'Helvetica Neue', helvetica, 'Lucida Grande', arial, sans-serif; + font-size: 14px; +} + +#graphiql-container .editorWrap { + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + flex: 1; +} + +#graphiql-container .title { + display: none; + font-size: 18px; +} + +#graphiql-container .title em { + font-family: georgia; + font-size: 19px; +} + +#graphiql-container .topBarWrap { + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + background: #F9F9F9; + height: 48px; +} + +#graphiql-container .topBar { + border-bottom: solid 1px #d0d0d0; + cursor: default; + -webkit-user-select: none; + user-select: none; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-flex: 1; + flex: 1; + -webkit-align-items: center; + align-items: center; +} + +#graphiql-container .docExplorerShow { + background: #F9F9F9; + border: none; + border-bottom: solid 1px #d0d0d0; + border-left: solid 1px rgba(0, 0, 0, 0.2); + color: #3B5998; + cursor: pointer; + font-size: 14px; + outline: 0; + padding: 2px 20px 0 18px; +} + +#graphiql-container .docExplorerShow:before { + border-left: 2px solid #3B5998; + border-top: 2px solid #3B5998; + content: ''; + display: inline-block; + height: 9px; + margin: 0 3px -1px 0; + position: relative; + width: 9px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +#graphiql-container .editorBar { + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-flex: 1; + flex: 1; +} + +#graphiql-container .queryWrap { + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + flex: 1; +} + +#graphiql-container .resultWrap { + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + -webkit-flex: 1; + flex: 1; + border-left: solid 1px #e0e0e0; +} + +#graphiql-container .docExplorerWrap { + box-shadow: 0 0 8px rgba(0, 0, 0, 0.15); + z-index: 3; + position: relative; + background: white; +} + +#graphiql-container .docExplorerResizer { + cursor: col-resize; + height: 100%; + left: -5px; + position: absolute; + top: 0; + width: 10px; + z-index: 10; +} + +#graphiql-container .docExplorerHide { + cursor: pointer; + font-size: 18px; + margin: -7px -8px -6px 0; + padding: 18px 16px 15px 12px; +} + +#graphiql-container .query-editor { + -webkit-flex: 1; + flex: 1; + position: relative; +} + +#graphiql-container .variable-editor { + height: 30px; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + position: relative; +} + +#graphiql-container .variable-editor-title { + background: #eeeeee; + border-bottom: solid 1px #d6d6d6; + border-top: solid 1px #e0e0e0; + color: #777; + font-variant: small-caps; + font-weight: bold; + letter-spacing: 1px; + line-height: 14px; + padding: 6px 0 8px 43px; + text-transform: lowercase; + -webkit-user-select: none; + user-select: none; +} + +#graphiql-container .codemirrorWrap { + -webkit-flex: 1; + flex: 1; + position: relative; +} + +#graphiql-container .result-window { + -webkit-flex: 1; + flex: 1; + position: relative; +} + +#graphiql-container .footer { + background: #f6f7f8; + border-left: solid 1px #e0e0e0; + border-top: solid 1px #e0e0e0; + margin-left: 12px; + position: relative; +} + +#graphiql-container .footer:before { + background: #eeeeee; + bottom: 0; + content: " "; + left: -13px; + position: absolute; + top: -1px; + width: 12px; +} + +#graphiql-container .result-window .CodeMirror { + background: #f6f7f8; +} + +#graphiql-container .result-window .CodeMirror-gutters { + background-color: #eeeeee; + border-color: #e0e0e0; + cursor: col-resize; +} + +#graphiql-container .result-window .CodeMirror-foldgutter, +#graphiql-container .result-window .CodeMirror-foldgutter-open:after, +#graphiql-container .result-window .CodeMirror-foldgutter-folded:after { + padding-left: 3px; +} + +#graphiql-container .execute-button { + background: white; + border: solid 1px #999; + border-radius: 17px; + box-shadow: 0 1px 0 #fff; + cursor: pointer; + fill: #444; + height: 34px; + margin: 0 14px 0 14px; + padding: 0; + width: 34px; +} + +#graphiql-container .execute-button:active { + background: #EEE; + box-shadow: + inset 0 0 2px rgba(0, 0, 0, 0.2), + inset 0 0 6px rgba(0, 0, 0, 0.1); +} + +#graphiql-container .execute-button:focus { + outline: 0; +} + +#graphiql-container .CodeMirror-scroll { + -webkit-overflow-scrolling: touch; +} + +#graphiql-container .CodeMirror { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + font-size: 13px; + font-family: 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace; + color: #141823; +} + +#graphiql-container .CodeMirror-lines { + padding: 20px 0; +} + +.CodeMirror-hint-information .content { + -webkit-box-orient: vertical; + color: #141823; + display: -webkit-box; + font-family: system, -apple-system, 'San Francisco', '.SFNSDisplay-Regular', 'Segoe UI', Segoe, 'Segoe WP', 'Helvetica Neue', helvetica, 'Lucida Grande', arial, sans-serif; + font-size: 13px; + -webkit-line-clamp: 3; + line-height: 16px; + max-height: 48px; + overflow: hidden; + text-overflow: -o-ellipsis-lastline; +} + +.CodeMirror-hint-information .content p:first-child { + margin-top: 0; +} + +.CodeMirror-hint-information .content p:last-child { + margin-bottom: 0; +} + +.CodeMirror-hint-information .infoType { + color: #30a; + margin-right: 0.5em; + display: inline; + cursor: pointer; +} + +.autoInsertedLeaf.cm-property { + padding: 2px 4px 1px; + margin: -2px -4px -1px; + border-radius: 2px; + border-bottom: solid 2px rgba(255, 255, 255, 0); + -webkit-animation-duration: 6s; + -moz-animation-duration: 6s; + animation-duration: 6s; + -webkit-animation-name: insertionFade; + -moz-animation-name: insertionFade; + animation-name: insertionFade; +} + +@-moz-keyframes insertionFade { + from, to { + background: rgba(255, 255, 255, 0); + border-color: rgba(255, 255, 255, 0); + } + + 15%, 85% { + background: #fbffc9; + border-color: #f0f3c0; + } +} + +@-webkit-keyframes insertionFade { + from, to { + background: rgba(255, 255, 255, 0); + border-color: rgba(255, 255, 255, 0); + } + + 15%, 85% { + background: #fbffc9; + border-color: #f0f3c0; + } +} + +@keyframes insertionFade { + from, to { + background: rgba(255, 255, 255, 0); + border-color: rgba(255, 255, 255, 0); + } + + 15%, 85% { + background: #fbffc9; + border-color: #f0f3c0; + } +} + +div.CodeMirror-lint-tooltip { + background-color: white; + color: #141823; + border: 0; + border-radius: 2px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + font-family: system, -apple-system, 'San Francisco', '.SFNSDisplay-Regular', 'Segoe UI', Segoe, 'Segoe WP', 'Helvetica Neue', helvetica, 'Lucida Grande', arial, sans-serif; + font-size: 13px; + line-height: 16px; + padding: 6px 10px; + opacity: 0; + transition: opacity 0.15s; + -moz-transition: opacity 0.15s; + -webkit-transition: opacity 0.15s; + -o-transition: opacity 0.15s; + -ms-transition: opacity 0.15s; +} + +div.CodeMirror-lint-message-error, div.CodeMirror-lint-message-warning { + padding-left: 23px; +} + +/* COLORS */ + +#graphiql-container .CodeMirror-foldmarker { + border-radius: 4px; + background: #08f; + background: -webkit-linear-gradient(#43A8FF, #0F83E8); + background: linear-gradient(#43A8FF, #0F83E8); + + color: white; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 0 0 1px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 0 0 1px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 0 0 1px rgba(0, 0, 0, 0.1); + font-family: arial; + line-height: 0; + padding: 0px 4px 1px; + font-size: 12px; + margin: 0 3px; + text-shadow: 0 -1px rgba(0, 0, 0, 0.1); +} + +#graphiql-container div.CodeMirror span.CodeMirror-matchingbracket { + color: #555; + text-decoration: underline; +} + +#graphiql-container div.CodeMirror span.CodeMirror-nonmatchingbracket { + color: #f00; +} + +/* Comment */ +.cm-comment { + color: #999; +} + +/* Punctuation */ +.cm-punctuation { + color: #555; +} + +/* Keyword */ +.cm-keyword { + color: #B11A04; +} + +/* OperationName, FragmentName */ +.cm-def { + color: #D2054E; +} + +/* FieldName */ +.cm-property { + color: #1F61A0; +} + +/* FieldAlias */ +.cm-qualifier { + color: #1C92A9; +} + +/* ArgumentName and ObjectFieldName */ +.cm-attribute { + color: #8B2BB9; +} + +/* Number */ +.cm-number { + color: #2882F9; +} + +/* String */ +.cm-string { + color: #D64292; +} + +/* Boolean */ +.cm-builtin { + color: #D47509; +} + +/* EnumValue */ +.cm-string-2 { + color: #0B7FC7; +} + +/* Variable */ +.cm-variable { + color: #397D13; +} + +/* Directive */ +.cm-meta { + color: #B33086; +} + +/* Type */ +.cm-atom { + color: #CA9800; +} +/* BASICS */ + +.CodeMirror { + /* Set height, width, borders, and global font properties here */ + font-family: monospace; + height: 300px; + color: black; +} + +/* PADDING */ + +.CodeMirror-lines { + padding: 4px 0; /* Vertical padding around content */ +} +.CodeMirror pre { + padding: 0 4px; /* Horizontal padding of content */ +} + +.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + background-color: white; /* The little square between H and V scrollbars */ +} + +/* GUTTER */ + +.CodeMirror-gutters { + border-right: 1px solid #ddd; + background-color: #f7f7f7; + white-space: nowrap; +} +.CodeMirror-linenumbers {} +.CodeMirror-linenumber { + padding: 0 3px 0 5px; + min-width: 20px; + text-align: right; + color: #999; + white-space: nowrap; +} + +.CodeMirror-guttermarker { color: black; } +.CodeMirror-guttermarker-subtle { color: #999; } + +/* CURSOR */ + +.CodeMirror div.CodeMirror-cursor { + border-left: 1px solid black; +} +/* Shown when moving in bi-directional text */ +.CodeMirror div.CodeMirror-secondarycursor { + border-left: 1px solid silver; +} +.CodeMirror.cm-fat-cursor div.CodeMirror-cursor { + width: auto; + border: 0; + background: #7e7; +} +.CodeMirror.cm-fat-cursor div.CodeMirror-cursors { + z-index: 1; +} + +.cm-animate-fat-cursor { + width: auto; + border: 0; + -webkit-animation: blink 1.06s steps(1) infinite; + -moz-animation: blink 1.06s steps(1) infinite; + animation: blink 1.06s steps(1) infinite; +} +@-moz-keyframes blink { + 0% { background: #7e7; } + 50% { background: none; } + 100% { background: #7e7; } +} +@-webkit-keyframes blink { + 0% { background: #7e7; } + 50% { background: none; } + 100% { background: #7e7; } +} +@keyframes blink { + 0% { background: #7e7; } + 50% { background: none; } + 100% { background: #7e7; } +} + +/* Can style cursor different in overwrite (non-insert) mode */ +div.CodeMirror-overwrite div.CodeMirror-cursor {} + +.cm-tab { display: inline-block; text-decoration: inherit; } + +.CodeMirror-ruler { + border-left: 1px solid #ccc; + position: absolute; +} + +/* DEFAULT THEME */ + +.cm-s-default .cm-keyword {color: #708;} +.cm-s-default .cm-atom {color: #219;} +.cm-s-default .cm-number {color: #164;} +.cm-s-default .cm-def {color: #00f;} +.cm-s-default .cm-variable, +.cm-s-default .cm-punctuation, +.cm-s-default .cm-property, +.cm-s-default .cm-operator {} +.cm-s-default .cm-variable-2 {color: #05a;} +.cm-s-default .cm-variable-3 {color: #085;} +.cm-s-default .cm-comment {color: #a50;} +.cm-s-default .cm-string {color: #a11;} +.cm-s-default .cm-string-2 {color: #f50;} +.cm-s-default .cm-meta {color: #555;} +.cm-s-default .cm-qualifier {color: #555;} +.cm-s-default .cm-builtin {color: #30a;} +.cm-s-default .cm-bracket {color: #997;} +.cm-s-default .cm-tag {color: #170;} +.cm-s-default .cm-attribute {color: #00c;} +.cm-s-default .cm-header {color: blue;} +.cm-s-default .cm-quote {color: #090;} +.cm-s-default .cm-hr {color: #999;} +.cm-s-default .cm-link {color: #00c;} + +.cm-negative {color: #d44;} +.cm-positive {color: #292;} +.cm-header, .cm-strong {font-weight: bold;} +.cm-em {font-style: italic;} +.cm-link {text-decoration: underline;} +.cm-strikethrough {text-decoration: line-through;} + +.cm-s-default .cm-error {color: #f00;} +.cm-invalidchar {color: #f00;} + +.CodeMirror-composing { border-bottom: 2px solid; } + +/* Default styles for common addons */ + +div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} +div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} +.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } +.CodeMirror-activeline-background {background: #e8f2ff;} + +/* STOP */ + +/* The rest of this file contains styles related to the mechanics of + the editor. You probably shouldn't touch them. */ + +.CodeMirror { + position: relative; + overflow: hidden; + background: white; +} + +.CodeMirror-scroll { + overflow: scroll !important; /* Things will break if this is overridden */ + /* 30px is the magic margin used to hide the element's real scrollbars */ + /* See overflow: hidden in .CodeMirror */ + margin-bottom: -30px; margin-right: -30px; + padding-bottom: 30px; + height: 100%; + outline: none; /* Prevent dragging from highlighting the element */ + position: relative; +} +.CodeMirror-sizer { + position: relative; + border-right: 30px solid transparent; +} + +/* The fake, visible scrollbars. Used to force redraw during scrolling + before actuall scrolling happens, thus preventing shaking and + flickering artifacts. */ +.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + position: absolute; + z-index: 6; + display: none; +} +.CodeMirror-vscrollbar { + right: 0; top: 0; + overflow-x: hidden; + overflow-y: scroll; +} +.CodeMirror-hscrollbar { + bottom: 0; left: 0; + overflow-y: hidden; + overflow-x: scroll; +} +.CodeMirror-scrollbar-filler { + right: 0; bottom: 0; +} +.CodeMirror-gutter-filler { + left: 0; bottom: 0; +} + +.CodeMirror-gutters { + position: absolute; left: 0; top: 0; + z-index: 3; +} +.CodeMirror-gutter { + white-space: normal; + height: 100%; + display: inline-block; + margin-bottom: -30px; + /* Hack to make IE7 behave */ + *zoom:1; + *display:inline; +} +.CodeMirror-gutter-wrapper { + position: absolute; + z-index: 4; + height: 100%; +} +.CodeMirror-gutter-elt { + position: absolute; + cursor: default; + z-index: 4; +} +.CodeMirror-gutter-wrapper { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.CodeMirror-lines { + cursor: text; + min-height: 1px; /* prevents collapsing before first draw */ +} +.CodeMirror pre { + /* Reset some styles that the rest of the page might have set */ + -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; + border-width: 0; + background: transparent; + font-family: inherit; + font-size: inherit; + margin: 0; + white-space: pre; + word-wrap: normal; + line-height: inherit; + color: inherit; + z-index: 2; + position: relative; + overflow: visible; + -webkit-tap-highlight-color: transparent; +} +.CodeMirror-wrap pre { + word-wrap: break-word; + white-space: pre-wrap; + word-break: normal; +} + +.CodeMirror-linebackground { + position: absolute; + left: 0; right: 0; top: 0; bottom: 0; + z-index: 0; +} + +.CodeMirror-linewidget { + position: relative; + z-index: 2; + overflow: auto; +} + +.CodeMirror-widget {} + +.CodeMirror-code { + outline: none; +} + +/* Force content-box sizing for the elements where we expect it */ +.CodeMirror-scroll, +.CodeMirror-sizer, +.CodeMirror-gutter, +.CodeMirror-gutters, +.CodeMirror-linenumber { + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +.CodeMirror-measure { + position: absolute; + width: 100%; + height: 0; + overflow: hidden; + visibility: hidden; +} +.CodeMirror-measure pre { position: static; } + +.CodeMirror div.CodeMirror-cursor { + position: absolute; + border-right: none; + width: 0; +} + +div.CodeMirror-cursors { + visibility: hidden; + position: relative; + z-index: 3; +} +.CodeMirror-focused div.CodeMirror-cursors { + visibility: visible; +} + +.CodeMirror-selected { background: #d9d9d9; } +.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } +.CodeMirror-crosshair { cursor: crosshair; } +.CodeMirror ::selection { background: #d7d4f0; } +.CodeMirror ::-moz-selection { background: #d7d4f0; } + +.cm-searching { + background: #ffa; + background: rgba(255, 255, 0, .4); +} + +/* IE7 hack to prevent it from returning funny offsetTops on the spans */ +.CodeMirror span { *vertical-align: text-bottom; } + +/* Used to force a border model for a node */ +.cm-force-border { padding-right: .1px; } + +@media print { + /* Hide the cursor when printing */ + .CodeMirror div.CodeMirror-cursors { + visibility: hidden; + } +} + +/* See issue #2901 */ +.cm-tab-wrap-hack:after { content: ''; } + +/* Help users use markselection to safely style text background */ +span.CodeMirror-selectedtext { background: none; } +#graphiql-container .doc-explorer { + background: white; +} + +#graphiql-container .doc-explorer-title-bar { + cursor: default; + display: -webkit-flex; + display: flex; + height: 34px; + line-height: 14px; + padding: 8px 8px 5px; + position: relative; + -webkit-user-select: none; + user-select: none; +} + +#graphiql-container .doc-explorer-title { + padding: 10px 0 10px 10px; + font-weight: bold; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + overflow-x: hidden; + -webkit-flex: 1; + flex: 1; +} + +#graphiql-container .doc-explorer-back { + color: #3B5998; + cursor: pointer; + margin: -7px 0 -6px -8px; + overflow-x: hidden; + padding: 17px 12px 16px 16px; + text-overflow: ellipsis; + white-space: nowrap; +} + +#graphiql-container .doc-explorer-back:before { + border-left: 2px solid #3B5998; + border-top: 2px solid #3B5998; + content: ''; + display: inline-block; + height: 9px; + margin: 0 3px -1px 0; + position: relative; + width: 9px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +#graphiql-container .doc-explorer-rhs { + position: relative; +} + +#graphiql-container .doc-explorer-contents { + background-color: #ffffff; + border-top: 1px solid #d6d6d6; + bottom: 0; + left: 0; + min-width: 300px; + overflow-y: auto; + padding: 20px 15px; + position: absolute; + right: 0; + top: 47px; +} + +#graphiql-container .doc-type-description p:first-child , +#graphiql-container .doc-type-description blockquote:first-child { + margin-top: 0; +} + +#graphiql-container .doc-explorer-contents a { + cursor: pointer; + text-decoration: none; +} + +#graphiql-container .doc-explorer-contents a:hover { + text-decoration: underline; +} + +#graphiql-container .doc-value-description { + padding: 4px 0 8px 12px; +} + +#graphiql-container .doc-category { + margin: 20px 0; +} + +#graphiql-container .doc-category-title { + border-bottom: 1px solid #e0e0e0; + color: #777; + cursor: default; + font-size: 14px; + font-variant: small-caps; + font-weight: bold; + letter-spacing: 1px; + margin: 0 -15px 10px 0; + padding: 10px 0; + -webkit-user-select: none; + user-select: none; +} + +#graphiql-container .doc-category-item { + margin: 12px 0; + color: #555; +} + +#graphiql-container .keyword { + color: #B11A04; +} + +#graphiql-container .type-name { + color: #CA9800; +} + +#graphiql-container .field-name { + color: #1F61A0; +} + +#graphiql-container .value-name { + color: #0B7FC7; +} + +#graphiql-container .arg-name { + color: #8B2BB9; +} + +#graphiql-container .arg:after { + content: ', '; +} + +#graphiql-container .arg:last-child:after { + content: ''; +} +.CodeMirror-foldmarker { + color: blue; + text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; + font-family: arial; + line-height: .3; + cursor: pointer; +} +.CodeMirror-foldgutter { + width: .7em; +} +.CodeMirror-foldgutter-open, +.CodeMirror-foldgutter-folded { + cursor: pointer; +} +.CodeMirror-foldgutter-open:after { + content: "\25BE"; +} +.CodeMirror-foldgutter-folded:after { + content: "\25B8"; +} +/* The lint marker gutter */ +.CodeMirror-lint-markers { + width: 16px; +} + +.CodeMirror-lint-tooltip { + background-color: infobackground; + border: 1px solid black; + border-radius: 4px 4px 4px 4px; + color: infotext; + font-family: monospace; + font-size: 10pt; + overflow: hidden; + padding: 2px 5px; + position: fixed; + white-space: pre; + white-space: pre-wrap; + z-index: 100; + max-width: 600px; + opacity: 0; + transition: opacity .4s; + -moz-transition: opacity .4s; + -webkit-transition: opacity .4s; + -o-transition: opacity .4s; + -ms-transition: opacity .4s; +} + +.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { + background-position: left bottom; + background-repeat: repeat-x; +} + +.CodeMirror-lint-mark-error { + background-image: + url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") + ; +} + +.CodeMirror-lint-mark-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { + background-position: center center; + background-repeat: no-repeat; + cursor: pointer; + display: inline-block; + height: 16px; + width: 16px; + vertical-align: middle; + position: relative; +} + +.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { + padding-left: 18px; + background-position: top left; + background-repeat: no-repeat; +} + +.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-multiple { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); + background-repeat: no-repeat; + background-position: right bottom; + width: 100%; height: 100%; +} +.CodeMirror-hints { + background: white; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + font-family: 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace; + font-size: 13px; + list-style: none; + margin: 0; + margin-left: -6px; + max-height: 14.5em; + overflow-y: auto; + overflow: hidden; + padding: 0; + position: absolute; + z-index: 10; +} + +.CodeMirror-hints-wrapper { + background: white; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); + margin-left: -6px; + position: absolute; + z-index: 10; +} + +.CodeMirror-hints-wrapper .CodeMirror-hints { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + position: relative; + margin-left: 0; + z-index: 0; +} + +.CodeMirror-hint { + border-top: solid 1px #f7f7f7; + color: #141823; + cursor: pointer; + margin: 0; + max-width: 300px; + overflow: hidden; + padding: 2px 6px; + white-space: pre; +} + +li.CodeMirror-hint-active { + background-color: #08f; + border-top-color: white; + color: white; +} + +.CodeMirror-hint-information { + border-top: solid 1px #c0c0c0; + max-width: 300px; + padding: 4px 6px; + position: relative; + z-index: 1; +} + +.CodeMirror-hint-information:first-child { + border-bottom: solid 1px #c0c0c0; + border-top: none; + margin-bottom: -1px; +} diff --git a/docs/css/main.styl b/docs/css/main.styl index 0fafdf5e..b1481f11 100644 --- a/docs/css/main.styl +++ b/docs/css/main.styl @@ -1,12 +1,14 @@ @import 'nib' @import 'jeet' -@import 'hljs.css' -@import 'bm.css' @import 'https://fonts.googleapis.com/css?family=Raleway:400,500,600,200,100&.css' +global-reset() normalize-css() +@import 'hljs.css' +@import 'bm.css' + $wrapper center(960px, pad:20px) @@ -29,6 +31,9 @@ html, body font-size 16px color #606060 line-height 1.5 + height 100% + margin 0 + width 100% .header clearfix() @@ -332,7 +337,7 @@ $title margin-top 0 padding-top 0 -.title +.page-title background: #F9F9F9; padding 48px 0 diff --git a/docs/css/playground.styl b/docs/css/playground.styl new file mode 100644 index 00000000..7342bd5a --- /dev/null +++ b/docs/css/playground.styl @@ -0,0 +1,38 @@ +@import 'graphiql.css' + +.playground + position absolute + top 106px + left 0 + right 0 + bottom 0 + display flex + flex-direction row + min-width 960px + +.playground-schema + min-width 400px + width 36% + border-right 1px solid #E0E0E0 + box-shadow 0 0 8px rgba(0, 0, 0, 0.15) + position relative + z-index 100 + .CodeMirror + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + font-size: 13px; + font-family: 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace; + color: #141823; + + .cm-def + &.called-function + background rgba(219, 89, 76, .2) + border-radius 1px + box-shadow 0 0 0 3px rgba(219, 89, 76, .2) + +.playground-graphiql + flex 1 + height 100% diff --git a/docs/gatsby.config.js b/docs/gatsby.config.js index da6afec6..7b9c7f27 100644 --- a/docs/gatsby.config.js +++ b/docs/gatsby.config.js @@ -3,13 +3,24 @@ var jeet = require("jeet"); var rupture = require("rupture"); var path = require("path"); var ExtractTextPlugin = require("extract-text-webpack-plugin"); +var webpack = require("webpack"); var CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = function(config, env) { var IS_STATIC = env === 'static'; + var entry = config._config.entry.slice(); + // var output = config._config.output; + // output.filename = "[name].js"; + config._config.entry = { + bundle: entry, + }; config.merge({ - stylus: { - use: [nib(), jeet(), rupture()] + stylus: { + use: [nib(), jeet(), rupture()] + }, + output: { + filename: "[name].js", + publicPath: "/", }, resolveLoader: { root: path.join(__dirname, "node_modules"), @@ -23,7 +34,9 @@ module.exports = function(config, env) { alias: { 'original-react': path.join(__dirname, "node_modules", "react"), 'react/lib': path.join(__dirname, "node_modules", "react", "lib"), - 'react': path.join(__dirname, 'patched-react.js') + 'react': path.join(__dirname, 'patched-react.js'), + 'playground-page': (env != "static")?'../playground/page':'../pages/_empty', + 'playground-wrapper': (env == "develop")?'../playground/page':'../playground/wrapper', }, modulesDirectories: ['./'] } @@ -32,6 +45,10 @@ module.exports = function(config, env) { config.plugin('extract-css', ExtractTextPlugin, ["app.css"]); } config.plugin('static', CopyWebpackPlugin, [[{ from: '../static'}]]); + config.plugin('define-env', webpack.DefinePlugin, [{"ENV": JSON.stringify(env)}]); + // if (env != "static") { + // config.plugin('commons', webpack.optimize.CommonsChunkPlugin, ["commons.js"]); + // } config.loader('stylus', function(cfg) { cfg.test = /\.styl$/; diff --git a/docs/package.json b/docs/package.json index efaa1c67..185d6160 100644 --- a/docs/package.json +++ b/docs/package.json @@ -16,6 +16,9 @@ "copy-webpack-plugin": "^0.2.0", "extract-text-webpack-plugin": "^0.9.1", "gatsby": "^0.7.2", + "graphiql": "^0.4.2", + "graphql": "^0.4.13", + "codemirror": "5.9.0", "jeet": "^6.1.2", "lodash": "^3.10.1", "nib": "^1.1.0", diff --git a/docs/pages/_empty.js b/docs/pages/_empty.js new file mode 100644 index 00000000..5932606e --- /dev/null +++ b/docs/pages/_empty.js @@ -0,0 +1,9 @@ +import React from 'react'; + +class Empty extends React.Component { + render() { + return
; + } +} + +module.exports = Empty; diff --git a/docs/pages/_template.js b/docs/pages/_template.js index 385239dd..18f32948 100644 --- a/docs/pages/_template.js +++ b/docs/pages/_template.js @@ -14,7 +14,7 @@ class Template extends React.Component { return (
- Try it out + Try it out Docs Community Github @@ -26,7 +26,7 @@ class Template extends React.Component { Graphene