Beispiel #1
0
    def test_dot_lookup(self):
        self.assertEqual(dot_lookup({'a': {'b': 'hello'}}, 'a.b'), 'hello')
        self.assertEqual(dot_lookup({'a': {'b': 'hello'}}, ['a', 'b']),
                         'hello')

        self.assertEqual(dot_lookup({'a': {'b': 'hello'}}, 'a.b', parent=True),
                         {'b': 'hello'})
        self.assertEqual(dot_lookup({'a': {'b': 'hello'}}, ''),
                         {'a': {'b': 'hello'}})
Beispiel #2
0
    def render(self):
        # TODO: Fix it so only changed components are updated
        # for widget in self._frame.winfo_children():
        #     widget.destroy()

        # Recursively build component tree dict
        root_tree = parse_component_tree(self._root_comp())

        if self._old_tree is not None:
            delta = diff(self._old_tree,
                         root_tree,
                         ignore=('_comp_obj', '_comp_update'))

            for diff_type, index, data in delta:
                if isinstance(index, str) or len(index) == 1:
                    # Top-level change
                    old_node = self._old_tree
                else:
                    # Sub-node change
                    old_node = dot_lookup(self._old_tree, index[:-1])

                # Update node props
                if diff_type == 'change':
                    update_fn = old_node['_comp_update']
                    new_node = dot_lookup(root_tree, index[:-1])
                    new_node['_comp_update'] = update_fn
                    new_node['_comp_obj'] = old_node['_comp_obj']
                    if update_fn is not None:
                        update_fn(text=new_node['text'], **new_node['_props'])

                # # Copy component info

                # Update new node in root tree (if new one created)

                # patch([('change', index[:-1], (old_node2, new_node))], root_tree)
        else:
            render_list = [(root_tree, None)]
            self.render_component(root_tree)
        # TODO: Diff tree against existing tree

        # Instantiate or modify components as needed (pack(), update() or destroy())

        self._dirty = False
        self._old_tree = root_tree
Beispiel #3
0
def patch(differences, lTree, rTree, lDict, rDict, out):

    root = etree.Element('diff')

    for difference in differences:
        type = difference[0]
        path = difference[1]
        change = difference[2]

        if type == 'change':
            if 'attrib' in path:
                split = path.split('.attrib.')
                parent_path = path.split('.attrib.')[0]
                attrib = path.split('.attrib.')[1]
                lnode = dot_lookup(lDict, parent_path)
                replace = etree.SubElement(
                    root,
                    'replace',
                    attrib={'sel': lnode['path'] + '/@' + attrib})
                replace.text = change[1]
            else:
                lnode = dot_lookup(lDict, path, parent=True)
                replace = etree.SubElement(
                    root, 'replace', attrib={'sel': lnode['path'] + '/text()'})
                replace.text = change[1]
        elif type == 'add':
            if 'attrib' in path:
                for c in change:
                    lnode = dot_lookup(lDict, path, parent=True)
                    add = etree.SubElement(root,
                                           'add',
                                           attrib={
                                               'sel': lnode['path'],
                                               'type': '@' + c[0]
                                           })
                    add.text = c[1]
            else:
                for c in change:
                    xpath = c[0]
                    relement = rTree.xpath(xpath)[0]
                    lelement = relement.getprevious()
                    if lelement is not None:
                        xpath = better_xpath(lelement, rTree)
                        add = etree.SubElement(root,
                                               'add',
                                               attrib={
                                                   'sel': xpath,
                                                   'pos': 'after'
                                               })
                        add.insert(0, deepcopy(relement))
                    else:
                        lelement = relement.getparent()
                        xpath = better_xpath(lelement, rTree)
                        add = etree.SubElement(root,
                                               'add',
                                               attrib={
                                                   'sel': xpath,
                                                   'pos': 'prepend'
                                               })
                        add.insert(0, deepcopy(relement))
        elif type == 'remove':
            if 'attrib' in path:
                for c in change:
                    lnode = dot_lookup(lDict, path, parent=True)
                    remove = etree.SubElement(
                        root,
                        'remove',
                        attrib={'sel': lnode['path'] + '/@' + c[0]})
            else:
                for c in change:
                    xpath = c[0]
                    etree.SubElement(root, 'remove', attrib={'sel': xpath})

    et = etree.ElementTree(root)
    et.write(out, xml_declaration=True, encoding='utf-8', pretty_print=True)