Esempio n. 1
0
 def switch_mode(self):
     settings, request, response, T = self.settings, current.request, current.response, current.T
     
     _arg0 = request.args(0)
     if not (_arg0 and (EDIT_MODE in _arg0 or PREVIEW_MODE in _arg0 or  REFERENCE_MODE in _arg0)):
         self.view_mode = LIVE_MODE
         return
     else:
         self.view_mode = _arg0
         current_device = None
         for device in self.settings.devices:
             suffix = '_managed_html_%s'%device['name']
             if suffix in _arg0:
                 request.update(**device.get('request_updator', {}))
                 current_device = device
                 break
         
         if request.args and request.args[-1] == 'managed_html.js':
             # Return javascript
             
             from globals import Response, Storage
             _response = Response()
             _response._view_environment = current.globalenv.copy()
             _response._view_environment.update(
                 request=Storage(folder=os.path.join(os.path.dirname(os.path.dirname(request.folder)), APP)),
                 response=_response,
             )
             
             _device_url_base = self.view_mode
             for device in self.settings.devices:
                 _device_url_base = _device_url_base.replace('_managed_html_%s' % device['name'], '')
             for device in self.settings.devices:
                 device.update({'url':self.settings.URL(args=[_device_url_base + '_managed_html_%s' % device['name']] + request.args[1:-1], vars=request.vars)})
             
             _response.headers['Content-Type'] = 'text/javascript; charset=utf-8;'
             raise HTTP(200, _response.render('plugin_managed_html/managed_html_ajax.js',
                         dict(
                             home_url=settings.home_url,
                             home_label=settings.home_label,
                             edit_url=settings.URL(args=[self.view_mode.replace(PREVIEW_MODE, EDIT_MODE).replace(REFERENCE_MODE, EDIT_MODE)] +
                                                         request.args[1:-1], vars=request.vars)
                                         if PREVIEW_MODE in self.view_mode or REFERENCE_MODE in self.view_mode else '',
                             preview_url=settings.URL(args=[self.view_mode.replace(EDIT_MODE, PREVIEW_MODE).replace(REFERENCE_MODE, PREVIEW_MODE)] +
                                                              request.args[1:-1], vars=request.vars)
                                         if EDIT_MODE in self.view_mode or REFERENCE_MODE in self.view_mode else '',
                             reference_url=settings.URL(args=[self.view_mode.replace(EDIT_MODE, REFERENCE_MODE).replace(PREVIEW_MODE, REFERENCE_MODE).replace('_managed_html_%s' % current_device['name'] if current_device else '', '')] +
                                                              request.args[1:-1], vars=request.vars)
                                         if EDIT_MODE in self.view_mode or PREVIEW_MODE in self.view_mode else '',
                             live_url=self.settings.URL(args=request.args[1:-1], vars=request.vars, scheme='http'),
                             show_page_grid=self._show_page_grid_js() if settings.page_grid else '',
                             devices=self.settings.devices,
                             current_device=current_device,
                             is_edit_mode=EDIT_MODE in self.view_mode,
                             is_preview_mode=PREVIEW_MODE in self.view_mode,
                         )),
                        **_response.headers)
         
         response.files.append(URL(args=((request.args or []) + ['managed_html.js'])))
         self.use_grid(args=request.args[:2])
Esempio n. 2
0
 def switch_mode(self):
     settings, request, response, T = self.settings, current.request, current.response, current.T
     
     _arg0 = request.args(0)
     if not (_arg0 and (EDIT_MODE in _arg0 or PREVIEW_MODE in _arg0)):
         self.view_mode = LIVE_MODE
         return
     else:
         self.view_mode = _arg0
         if request.args and request.args[-1] == 'managed_html.js':
             # Return javascript
             
             from globals import Response, Storage
             _response = Response()
             _response._view_environment = current.globalenv.copy()
             _response._view_environment.update(
                 request=Storage(folder=os.path.join(os.path.dirname(os.path.dirname(request.folder)), APP)),
                 response=_response,
             )
             
             _response.headers['Content-Type'] = 'text/javascript; charset=utf-8;'
             raise HTTP(200, _response.render('plugin_managed_html/managed_html_ajax.js',
                         dict(
                             home_url=settings.home_url,
                             home_label=settings.home_label,
                             edit_url=settings.URL(args=[self.view_mode.replace(PREVIEW_MODE, EDIT_MODE)] +
                                                         request.args[1:-1], vars=request.vars)
                                         if PREVIEW_MODE in self.view_mode else '',
                             preview_url=settings.URL(args=[self.view_mode.replace(EDIT_MODE, PREVIEW_MODE)] +
                                                              request.args[1:-1], vars=request.vars)
                                         if EDIT_MODE in self.view_mode else '',
                             live_url=self.settings.URL(args=request.args[1:-1], vars=request.vars, scheme='http'),
                             show_page_grid=self._show_page_grid_js() if settings.page_grid else '',
                         )),
                        **_response.headers)
                        
         response.files.append(URL(args=((request.args or []) + ['managed_html.js'])))
                       
         self.use_grid(args=request.args[:2])
Esempio n. 3
0
def LOAD(c=None, f='index', args=None, vars=None,
         extension=None, target=None, ajax=False, ajax_trap=False,
         url=None, user_signature=False, timeout=None, times=1,
         content='loading...', **attr):
    """  LOAD a component into the action's document

    Timing options:
    -times: An integer or string ("infinity"/"continuous")
    specifies how many times the component is requested
    -timeout (milliseconds): specifies the time to wait before
    starting the request or the frequency if times is greater than
    1 or "infinity".
    Timing options default to the normal behavior. The component
    is added on page loading without delay.
    """
    from html import TAG, DIV, URL, SCRIPT, XML
    if args is None:
        args = []
    vars = Storage(vars or {})
    target = target or 'c' + str(random.random())[2:]
    attr['_id'] = target
    request = current.request
    if '.' in f:
        f, extension = f.rsplit('.', 1)
    if url or ajax:
        url = url or URL(request.application, c, f, r=request,
                         args=args, vars=vars, extension=extension,
                         user_signature=user_signature)
        # timing options
        if isinstance(times, basestring):
            if times.upper() in ("INFINITY", "CONTINUOUS"):
                times = "Infinity"
            else:
                raise TypeError("Unsupported times argument %s" % times)
        elif isinstance(times, int):
            if times <= 0:
                raise ValueError("Times argument must be greater than zero, 'Infinity' or None")
        else:
            raise TypeError("Unsupported times argument type %s" % type(times))
        if timeout is not None:
            if not isinstance(timeout, (int, long)):
                raise ValueError("Timeout argument must be an integer or None")
            elif timeout <= 0:
                raise ValueError(
                    "Timeout argument must be greater than zero or None")
            statement = "web2py_component('%s','%s', %s, %s);" \
                % (url, target, timeout, times)
        else:
            statement = "web2py_component('%s','%s');" % (url, target)
        script = SCRIPT(statement, _type="text/javascript")
        if not content is None:
            return TAG[''](script, DIV(content, **attr))
        else:
            return TAG[''](script)

    else:
        if not isinstance(args, (list, tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage(request)
        other_request['env'] = Storage(request.env)
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = Storage()
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application, c, f] +
                     map(str, other_request.args))
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_response.view = '%s/%s.%s' % (c, f, other_request.extension)

        other_environment = copy.copy(current.globalenv)  # NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            other_response._view_environment.update(page)
            run_view_in(other_response._view_environment)
            page = other_response.body.getvalue()
        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application, c, f, r=request,
                       args=args, vars=vars, extension=extension,
                       user_signature=user_signature)
            js = "web2py_trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js, _type="text/javascript") or ''
        return TAG[''](DIV(XML(page), **attr), script)
Esempio n. 4
0
def LOAD(c=None, f='index', args=None, vars=None,
         extension=None, target=None,ajax=False,ajax_trap=False,
         url=None,user_signature=False, timeout=None, times=1,
         content='loading...',**attr):
    """  LOAD a component into the action's document

    Timing options:
    -times: An integer or string ("infinity"/"continuous")
    specifies how many times the component is requested
    -timeout (milliseconds): specifies the time to wait before
    starting the request or the frequency if times is greater than
    1 or "infinity".
    Timing options default to the normal behavior. The component
    is added on page loading without delay.
    """
    from html import TAG, DIV, URL, SCRIPT, XML
    if args is None: args = []
    vars = Storage(vars or {})
    target = target or 'c'+str(random.random())[2:]
    attr['_id']=target
    request = current.request
    if '.' in f:
        f, extension = f.rsplit('.',1)
    if url or ajax:
        url = url or URL(request.application, c, f, r=request,
                         args=args, vars=vars, extension=extension,
                         user_signature=user_signature)
        # timing options
        if isinstance(times, basestring):
            if times.upper() in ("INFINITY", "CONTINUOUS"):
                times = "Infinity"
            else:
                raise TypeError("Unsupported times argument %s" % times)
        elif isinstance(times, int):
            if times <= 0:
                raise ValueError("Times argument must be greater than zero, 'Infinity' or None")
        else:
            raise TypeError("Unsupported times argument type %s" % type(times))
        if timeout is not None:
            if not isinstance(timeout, (int, long)):
                raise ValueError("Timeout argument must be an integer or None")
            elif timeout <= 0:
                raise ValueError("Timeout argument must be greater than zero or None")
            statement = "web2py_component('%s','%s', %s, %s);" \
            % (url, target, timeout, times)
        else:
            statement = "web2py_component('%s','%s');" % (url, target)
        script = SCRIPT(statement, _type="text/javascript")
        if not content is None:
            return TAG[''](script, DIV(content,**attr))
        else:
            return TAG[''](script)

    else:
        if not isinstance(args,(list,tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage(request)
        other_request['env'] = Storage(request.env)
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = Storage()
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application,c,f] + \
                         map(str, other_request.args))
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_response.view = '%s/%s.%s' % (c,f, other_request.extension)

        other_environment = copy.copy(current.globalenv) ### NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            other_response._view_environment.update(page)
            run_view_in(other_response._view_environment)
            page = other_response.body.getvalue()
        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application, c, f, r=request,
                            args=args, vars=vars, extension=extension,
                            user_signature=user_signature)
            js = "web2py_trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js,_type="text/javascript") or ''
        return TAG[''](DIV(XML(page),**attr),script)
Esempio n. 5
0
    def __call__(
            self,
            args=[],
            user_signature=True,
            hmac_key=None,
            onsuccess=None,  # def onsuccess(affected_node_ids): ...
    ):
        request = current.request

        def url(**b):
            b['args'] = args + b.get('args', [])
            b['user_signature'] = user_signature
            b['hmac_key'] = hmac_key
            return URL(**b)

        def check_authorization():
            if not URL.verify(
                    request, user_signature=user_signature, hmac_key=hmac_key):
                raise HTTP(403)

        action = request.args and request.args[-1]

        if action == 'new':
            check_authorization()
            vars = request.post_vars
            if not vars.name or vars.name == '---':
                raise HTTP(406)
            node_id = self.tree_model.insert_node(vars.target, name=vars.name)
            if onsuccess:
                onsuccess([])
            raise HTTP(200, node_id)

        elif action == 'edit':
            check_authorization()
            vars = request.post_vars
            if not vars.name or vars.name == '---':
                raise HTTP(406)
            node = self.tree_model.get_node(vars.id)
            if not node:
                raise HTTP(404)
            if node.name == vars.name:
                raise HTTP(406)
            node.update_record(name=vars.name)
            if onsuccess:
                onsuccess([])
            raise HTTP(200)

        elif action == 'delete':
            check_authorization()
            vars = request.post_vars
            node = self.tree_model.get_node(vars.id)
            if not self.tree_model.is_leaf_node(node) or not node:
                raise HTTP(404)
            affected_node_ids = [
                _node.id for _node in self.tree_model.ancestors_from_node(
                    node).select()
            ]

            self.tree_model.delete_node(node)
            if onsuccess:
                onsuccess(affected_node_ids)
            raise HTTP(200)

        elif action == 'move':
            check_authorization()
            vars = request.post_vars
            node = self.tree_model.get_node(vars.id)
            if self.tree_model.is_root_node(node):
                raise HTTP(406)
            affected_node_ids = [
                _node.id for _node in self.tree_model.ancestors_from_node(
                    node).select()
            ]

            parent_node = self.tree_model.get_node(vars.parent)
            position = int(vars.position)

            target_child = self.tree_model.get_first_child(parent_node)
            if target_child:
                tmp = None
                end_flag = False
                for i in range(position):
                    tmp = self.tree_model.get_next_sibling(target_child)
                    if tmp is False:
                        self.tree_model.move_node(node, target_child, 'right')
                        end_flag = True
                    target_child = tmp
                if end_flag is False:
                    self.tree_model.move_node(node, target_child, 'left')
            else:
                self.tree_model.move_node(node, parent_node)

            affected_node_ids += [
                _node.id for _node in self.tree_model.ancestors_from_node(
                    node).select()
            ]
            if onsuccess:
                onsuccess(list(set(affected_node_ids)))

            raise HTTP(200)

        root_nodes = self.tree_model.roots().select()
        data = []
        initially_open = []
        for i, root_node in enumerate(root_nodes):
            _data, _initially_open = self.build_tree_objects(root_node)
            data.append(_data)
            initially_open += _initially_open

        from gluon.utils import web2py_uuid
        element_id = web2py_uuid()

        from globals import Response, Storage
        _response = Response()
        _response._view_environment = current.globalenv.copy()
        _response._view_environment.update(
            request=Storage(folder=os.path.join(
                os.path.dirname(os.path.dirname(request.folder)), APP)),
            response=_response,
        )
        return XML(
            _response.render(
                'plugin_jstree/block.html',
                dict(url=url,
                     data=data,
                     initially_open=initially_open,
                     tree_crud_buttons=self.render_tree_crud_buttons(),
                     element_id=element_id,
                     APP=APP)))
Esempio n. 6
0
def LOAD(c=None, f='index', args=None, vars=None,
         extension=None, target=None,ajax=False,ajax_trap=False,
         url=None,user_signature=False, content='loading...',**attr):
    from html import TAG, DIV, URL, SCRIPT, XML
    if args is None: args = []
    vars = Storage(vars or {})
    target = target or 'c'+str(random.random())[2:]
    attr['_id']=target
    request = current.request
    if '.' in f:
        f, extension = f.split('.',1)
    if url or ajax:
        url = url or URL(request.application, c, f, r=request,
                         args=args, vars=vars, extension=extension,
                         user_signature=user_signature)
        script = SCRIPT('web2py_component("%s","%s")' % (url, target),
                             _type="text/javascript")
        return TAG[''](script, DIV(content,**attr))
    else:
        if not isinstance(args,(list,tuple)):
            args = [args]
        c = c or request.controller        
        other_request = Storage()
        for key, value in request.items():
            other_request[key] = value
        other_request['env'] = Storage()
        for key, value in request.env.items():
            other_request.env['key'] = value
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = Storage()
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application,c,f] + \
                         map(str, other_request.args))
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_response.view = '%s/%s.%s' % (c,f, other_request.extension)

        other_environment = copy.copy(current.globalenv) ### NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response
        
        ## some magic here because current are thread-locals
        
        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            for key in page:
                other_response._view_environment[key] = page[key]
            run_view_in(other_response._view_environment)
            page = other_response.body.getvalue()
        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application, c, f, r=request,
                            args=args, vars=vars, extension=extension,
                            user_signature=user_signature)
            js = "web2py_trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js,_type="text/javascript") or ''
        return TAG[''](DIV(XML(page),**attr),script)
Esempio n. 7
0
    def __call__(self,
                 args=[],
                 user_signature=True,
                 hmac_key=None,
                 onsuccess=None,  # def onsuccess(affected_node_ids): ...
                 ):
        request = current.request
        
        def url(**b):
            b['args'] = args + b.get('args', [])
            b['user_signature'] = user_signature
            b['hmac_key'] = hmac_key
            return URL(**b)
        
        def check_authorization():
            if not URL.verify(request, user_signature=user_signature, hmac_key=hmac_key):
                raise HTTP(403)
                
        action = request.args and request.args[-1]
      
        if action == 'new':
            check_authorization()
            vars = request.post_vars
            if not vars.name or vars.name == '---':
                raise HTTP(406)
            node_id = self.tree_model.insert_node(vars.target, name=vars.name)
            if onsuccess:
                onsuccess([])
            raise HTTP(200, node_id)
            
        elif action == 'edit':
            check_authorization()
            vars = request.post_vars
            if not vars.name or vars.name == '---':
                raise HTTP(406)
            node = self.tree_model.get_node(vars.id)
            if not node:
                raise HTTP(404)
            if node.name == vars.name:
                raise HTTP(406)
            node.update_record(name=vars.name)
            if onsuccess:
                onsuccess([])
            raise HTTP(200)
            
        elif action == 'delete':
            check_authorization()
            vars = request.post_vars
            node = self.tree_model.get_node(vars.id)
            if not self.tree_model.is_leaf_node(node) or not node:
                raise HTTP(404)
            affected_node_ids = [_node.id for _node in self.tree_model.ancestors_from_node(node).select()]

            self.tree_model.delete_node(node)
            if onsuccess:
                onsuccess(affected_node_ids)
            raise HTTP(200)
            
        elif action == 'move':
            check_authorization()
            vars = request.post_vars
            node = self.tree_model.get_node(vars.id)
            if self.tree_model.is_root_node(node):
                raise HTTP(406)
            affected_node_ids = [_node.id for _node in self.tree_model.ancestors_from_node(node).select()]
            
            parent_node = self.tree_model.get_node(vars.parent)
            position = int(vars.position)
            
            target_child = self.tree_model.get_first_child(parent_node)
            if target_child:
                tmp = None
                end_flag = False
                for i in range(position):
                    tmp = self.tree_model.get_next_sibling(target_child)
                    if tmp is False:
                        self.tree_model.move_node(node, target_child, 'right')
                        end_flag = True
                    target_child = tmp
                if end_flag is False:
                    self.tree_model.move_node(node, target_child, 'left')
            else:
                self.tree_model.move_node(node, parent_node)
                
            affected_node_ids += [_node.id for _node in self.tree_model.ancestors_from_node(node).select()]
            if onsuccess:
                onsuccess(list(set(affected_node_ids)))
                
            raise HTTP(200)

        root_nodes = self.tree_model.roots().select()
        data = []
        initially_open = []
        for i, root_node in enumerate(root_nodes):
            _data, _initially_open = self.build_tree_objects(root_node)
            data.append(_data)
            initially_open += _initially_open
        
        from gluon.utils import web2py_uuid
        element_id = web2py_uuid()

        from globals import Response, Storage
        _response = Response()
        _response._view_environment = current.globalenv.copy()
        _response._view_environment.update(
            request=Storage(folder=os.path.join(os.path.dirname(os.path.dirname(request.folder)), APP)),
            response=_response,
        )
        return XML(_response.render('plugin_jstree/block.html',
                                   dict(url=url, data=data,
                                        initially_open=initially_open,
                                        tree_crud_buttons=self.render_tree_crud_buttons(),
                                        element_id=element_id,
                                        APP=APP)))
Esempio n. 8
0
def LOAD(c=None, f='index', args=None, vars=None,
         extension=None, target=None,ajax=False,ajax_trap=False,
         url=None,user_signature=False, content='loading...',**attr):
    from html import TAG, DIV, URL, SCRIPT, XML
    if args is None: args = []
    vars = Storage(vars or {})
    target = target or 'c'+str(random.random())[2:]
    attr['_id']=target
    request = current.request
    if '.' in f:
        f, extension = f.split('.',1)
    if url or ajax:
        url = url or URL(request.application, c, f, r=request,
                         args=args, vars=vars, extension=extension,
                         user_signature=user_signature)
        script = SCRIPT('web2py_component("%s","%s")' % (url, target),
                             _type="text/javascript")
        return TAG[''](script, DIV(content,**attr))
    else:
        if not isinstance(args,(list,tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage()
        for key, value in request.items():
            other_request[key] = value
        other_request['env'] = Storage()
        for key, value in request.env.items():
            other_request.env['key'] = value
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = Storage()
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application,c,f] + \
                         map(str, other_request.args))
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_response.view = '%s/%s.%s' % (c,f, other_request.extension)

        other_environment = copy.copy(current.globalenv) ### NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            for key in page:
                other_response._view_environment[key] = page[key]
            run_view_in(other_response._view_environment)
            page = other_response.body.getvalue()
        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application, c, f, r=request,
                            args=args, vars=vars, extension=extension,
                            user_signature=user_signature)
            js = "web2py_trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js,_type="text/javascript") or ''
        return TAG[''](DIV(XML(page),**attr),script)