Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: third_party/handlebar/handlebar.py

Issue 73963003: Docserver: roll third_party/handlebar/handlebar.py and tiny server2 change to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/handlebar/README.chromium ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2012 Benjamin Kalman 1 # Copyright 2012 Benjamin Kalman
2 # 2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License. 4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at 5 # You may obtain a copy of the License at
6 # 6 #
7 # http://www.apache.org/licenses/LICENSE-2.0 7 # http://www.apache.org/licenses/LICENSE-2.0
8 # 8 #
9 # Unless required by applicable law or agreed to in writing, software 9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 10 # distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 def Push(self, context): 148 def Push(self, context):
149 self._nodes.append(_Contexts._Node(context)) 149 self._nodes.append(_Contexts._Node(context))
150 150
151 def Pop(self): 151 def Pop(self):
152 node = self._nodes.pop() 152 node = self._nodes.pop()
153 assert len(self._nodes) >= self._first_local 153 assert len(self._nodes) >= self._first_local
154 for found_key in node.GetKeys(): 154 for found_key in node.GetKeys():
155 # [0] is the stack of nodes that |found_key| has been found in. 155 # [0] is the stack of nodes that |found_key| has been found in.
156 self._value_info[found_key][0].pop() 156 self._value_info[found_key][0].pop()
157 157
158 def FirstLocal(self):
159 if len(self._nodes) == self._first_local:
160 return None
161 return self._nodes[-1]._value
162
158 def Resolve(self, path): 163 def Resolve(self, path):
159 # This method is only efficient at finding |key|; if |tail| has a value (and 164 # This method is only efficient at finding |key|; if |tail| has a value (and
160 # |key| evaluates to an indexable value) we'll need to descend into that. 165 # |key| evaluates to an indexable value) we'll need to descend into that.
161 key, tail = path.split('.', 1) if '.' in path else (path, None) 166 key, tail = path.split('.', 1) if '.' in path else (path, None)
162 found = self._FindNodeValue(key) 167 found = self._FindNodeValue(key)
163 if tail is None: 168 if tail is None:
164 return found 169 return found
165 for part in tail.split('.'): 170 for part in tail.split('.'):
166 if not hasattr(found, 'get'): 171 if not hasattr(found, 'get'):
167 return None 172 return None
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 def Render(self, render_state): 641 def Render(self, render_state):
637 value = render_state.contexts.Resolve(self._id.name) 642 value = render_state.contexts.Resolve(self._id.name)
638 if value is None: 643 if value is None:
639 render_state.AddResolutionError(self._id) 644 render_state.AddResolutionError(self._id)
640 return 645 return
641 render_state.text.Append(json.dumps(value, separators=(',',':'))) 646 render_state.text.Append(json.dumps(value, separators=(',',':')))
642 647
643 def __repr__(self): 648 def __repr__(self):
644 return '{{*%s}}' % self._id 649 return '{{*%s}}' % self._id
645 650
651 # TODO: Better common model of _PartialNodeWithArguments, _PartialNodeInContext,
652 # and _PartialNode.
653 class _PartialNodeWithArguments(_DecoratorNode):
654 def __init__(self, partial, args):
655 if isinstance(partial, Handlebar):
656 # Preserve any get() method that the caller has added.
657 if hasattr(partial, 'get'):
658 self.get = partial.get
659 partial = partial._top_node
660 _DecoratorNode.__init__(self, partial)
661 self._partial = partial
662 self._args = args
663
664 def Render(self, render_state):
665 render_state.contexts.Scope(self._args, self._partial.Render, render_state)
666
667 class _PartialNodeInContext(_DecoratorNode):
668 def __init__(self, partial, context):
669 if isinstance(partial, Handlebar):
670 # Preserve any get() method that the caller has added.
671 if hasattr(partial, 'get'):
672 self.get = partial.get
673 partial = partial._top_node
674 _DecoratorNode.__init__(self, partial)
675 self._partial = partial
676 self._context = context
677
678 def Render(self, render_state):
679 original_contexts = render_state.contexts
680 try:
681 render_state.contexts = self._context
682 render_state.contexts.Scope(
683 # The first local context of |original_contexts| will be the
684 # arguments that were passed to the partial, if any.
685 original_contexts.FirstLocal() or {},
686 self._partial.Render, render_state)
687 finally:
688 render_state.contexts = original_contexts
689
646 class _PartialNode(_LeafNode): 690 class _PartialNode(_LeafNode):
647 '''{{+var:foo}} ... {{/foo}} 691 '''{{+var:foo}} ... {{/foo}}
648 ''' 692 '''
649 def __init__(self, bind_to, id_, content): 693 def __init__(self, bind_to, id_, content):
650 _LeafNode.__init__(self, id_.line, id_.line) 694 _LeafNode.__init__(self, id_.line, id_.line)
651 self._bind_to = bind_to 695 self._bind_to = bind_to
652 self._id = id_ 696 self._id = id_
653 self._content = content 697 self._content = content
654 self._resolved_args = None
655 self._args = None 698 self._args = None
656 self._pass_through_id = None 699 self._pass_through_id = None
657 700
658 @classmethod 701 @classmethod
659 def Inline(cls, id_): 702 def Inline(cls, id_):
660 return cls(None, id_, None) 703 return cls(None, id_, None)
661 704
662 def Render(self, render_state): 705 def Render(self, render_state):
663 value = render_state.contexts.Resolve(self._id.name) 706 value = render_state.contexts.Resolve(self._id.name)
664 if value is None: 707 if value is None:
665 render_state.AddResolutionError(self._id) 708 render_state.AddResolutionError(self._id)
666 return 709 return
667 if not isinstance(value, (Handlebar, _Node)): 710 if not isinstance(value, (Handlebar, _Node)):
668 render_state.AddResolutionError(self._id, description='not a partial') 711 render_state.AddResolutionError(self._id, description='not a partial')
669 return 712 return
670 713
671 if isinstance(value, Handlebar): 714 if isinstance(value, Handlebar):
672 node, name = value._top_node, value._name 715 node, name = value._top_node, value._name
673 else: 716 else:
674 node, name = value, None 717 node, name = value, None
675 718
676 partial_render_state = render_state.ForkPartial(name, self._id) 719 partial_render_state = render_state.ForkPartial(name, self._id)
677 720
678 arg_context = {} 721 arg_context = {}
679 if self._pass_through_id is not None: 722 if self._pass_through_id is not None:
680 context = render_state.contexts.Resolve(self._pass_through_id.name) 723 context = render_state.contexts.Resolve(self._pass_through_id.name)
681 if context is not None: 724 if context is not None:
682 arg_context[self._pass_through_id.name] = context 725 arg_context[self._pass_through_id.name] = context
683 if self._resolved_args is not None:
684 arg_context.update(self._resolved_args)
685 if self._args is not None: 726 if self._args is not None:
686 def resolve_args(args): 727 def resolve_args(args):
687 resolved = {} 728 resolved = {}
688 for key, value in args.iteritems(): 729 for key, value in args.iteritems():
689 if isinstance(value, dict): 730 if isinstance(value, dict):
690 assert len(value.keys()) == 1 731 assert len(value.keys()) == 1
691 inner_id, inner_args = value.items()[0] 732 id_of_partial, partial_args = value.items()[0]
692 inner_partial = render_state.contexts.Resolve(inner_id.name) 733 partial = render_state.contexts.Resolve(id_of_partial.name)
693 if inner_partial is not None: 734 if partial is not None:
694 context = _PartialNode(None, inner_id, inner_partial) 735 resolved[key] = _PartialNodeWithArguments(
695 context.SetResolvedArguments(resolve_args(inner_args)) 736 partial, resolve_args(partial_args))
696 resolved[key] = context
697 else: 737 else:
698 context = render_state.contexts.Resolve(value.name) 738 context = render_state.contexts.Resolve(value.name)
699 if context is not None: 739 if context is not None:
700 resolved[key] = context 740 resolved[key] = context
701 return resolved 741 return resolved
702 arg_context.update(resolve_args(self._args)) 742 arg_context.update(resolve_args(self._args))
703 if self._bind_to and self._content: 743 if self._bind_to and self._content:
704 arg_context[self._bind_to.name] = self._content 744 arg_context[self._bind_to.name] = _PartialNodeInContext(
745 self._content, render_state.contexts)
705 if arg_context: 746 if arg_context:
706 partial_render_state.contexts.Push(arg_context) 747 partial_render_state.contexts.Push(arg_context)
707 748
708 node.Render(partial_render_state) 749 node.Render(partial_render_state)
709 750
710 render_state.Merge( 751 render_state.Merge(
711 partial_render_state, 752 partial_render_state,
712 text_transform=lambda text: text[:-1] if text.endswith('\n') else text) 753 text_transform=lambda text: text[:-1] if text.endswith('\n') else text)
713 754
714 def SetResolvedArguments(self, args):
715 self._resolved_args = args
716
717 def SetArguments(self, args): 755 def SetArguments(self, args):
718 self._args = args 756 self._args = args
719 757
720 def PassThroughArgument(self, id_): 758 def PassThroughArgument(self, id_):
721 self._pass_through_id = id_ 759 self._pass_through_id = id_
722 760
723 def __repr__(self): 761 def __repr__(self):
724 return '{{+%s}}' % self._id 762 return '{{+%s}}' % self._id
725 763
726 _TOKENS = {} 764 _TOKENS = {}
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 id_ = _Identifier(tokens.AdvanceOverNextString(excluded=' \n\r\t:()'), 1123 id_ = _Identifier(tokens.AdvanceOverNextString(excluded=' \n\r\t:()'),
1086 tokens.next_line, 1124 tokens.next_line,
1087 column_start) 1125 column_start)
1088 tokens.SkipWhitespace() 1126 tokens.SkipWhitespace()
1089 return id_ 1127 return id_
1090 1128
1091 def Render(self, *user_contexts): 1129 def Render(self, *user_contexts):
1092 '''Renders this template given a variable number of contexts to read out 1130 '''Renders this template given a variable number of contexts to read out
1093 values from (such as those appearing in {{foo}}). 1131 values from (such as those appearing in {{foo}}).
1094 ''' 1132 '''
1095 name = self._name or '<root>'
1096 internal_context = _InternalContext() 1133 internal_context = _InternalContext()
1097 render_state = _RenderState( 1134 contexts = list(user_contexts)
1098 name, _Contexts([{'_': internal_context}] + list(user_contexts))) 1135 contexts.append({
1136 '_': internal_context,
1137 'false': False,
1138 'true': True,
1139 })
1140 render_state = _RenderState(self._name or '<root>', _Contexts(contexts))
1099 internal_context.SetRenderState(render_state) 1141 internal_context.SetRenderState(render_state)
1100 self._top_node.Render(render_state) 1142 self._top_node.Render(render_state)
1101 return render_state.GetResult() 1143 return render_state.GetResult()
1102 1144
1103 def render(self, *contexts): 1145 def render(self, *contexts):
1104 return self.Render(*contexts) 1146 return self.Render(*contexts)
1105 1147
1106 def __eq__(self, other): 1148 def __eq__(self, other):
1107 return self.source == other.source and self._name == other._name 1149 return self.source == other.source and self._name == other._name
1108 1150
1109 def __ne__(self, other): 1151 def __ne__(self, other):
1110 return not (self == other) 1152 return not (self == other)
1111 1153
1112 def __repr__(self): 1154 def __repr__(self):
1113 return str('%s(%s)' % (type(self).__name__, self._top_node)) 1155 return str('%s(%s)' % (type(self).__name__, self._top_node))
1114 1156
1115 def __str__(self): 1157 def __str__(self):
1116 return repr(self) 1158 return repr(self)
OLDNEW
« no previous file with comments | « third_party/handlebar/README.chromium ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698