def filter_stream(self, req, method, filename, stream, data):
        if filename == 'ticket.html' \
                and req.path_info.startswith('/newticket'):
            # common js files
            add_script(req, 'tt/json2.js')

            stream = stream | Transformer('body').append(
                tag.script("preview = %s;" % ('true' if 'preview' in req.args else 'false')) +
                tag.script(type='text/javascript',
                src=req.href('tt', 'tt_newticket.js'))()
            )

        return stream
    def filter_stream(self, req, method, filename, stream, data):
        if filename == 'ticket.html' \
                and req.path_info.startswith('/newticket'):
            # common js files
            add_script(req, 'tt/json2.js')

            stream = stream | Transformer('body').append(
                tag.script("preview = %s;" %
                           ('true' if 'preview' in req.args else 'false')) +
                tag.script(type='text/javascript',
                           src=req.href('tt', 'tt_newticket.js'))())

        return stream
示例#3
0
    def filter_stream(self, req, method, filename, stream, data):
        # Add Stylesheet here, so that the ticket page gets it too :)
        add_stylesheet(req, "clients/clients.css")

        newticket = req.path_info.startswith('/newticket')
        if req.path_info.startswith('/ticket/') or newticket:
            setdefaultrate = ''
            if newticket:
                setdefaultrate = "$('#field-client').trigger('change');"

            script = StringIO()
            script.write("""
              $(document).ready(function() {
                $('#field-client').change(function() {
                  """)
            script.write('var clientrates = new Array();')
            for client in Client.select(self.env):
                script.write('clientrates["%s"] = %s;' %
                             (client.name, client.default_rate or '""'))
            script.write("""
                  try { $('#field-clientrate').attr('value', clientrates[this.options[this.selectedIndex].value]); }
                  catch (er) { }
                });
                %s
             });""" % setdefaultrate)
            stream |= Transformer('.//head').append(
                tag.script(script.getvalue(), type_='text/javascript'))
        return stream
示例#4
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.path_info.startswith('/ticket'):
         button = tag.div(
             tag.input(type="submit",
                       title=_("Translate to %s") %
                       req.locale.get_display_name(),
                       value=_("Translate"),
                       forward=_("Translate"),
                       backward=_("Untranslate"),
                       working=_("Working"),
                       name="translate",
                       class_="translate"))
         button(class_="inlinebuttons")
         script = tag.script('')
         script(src='https://www.google.com/jsapi?key=' + self.googleApiKey)
         script(type='text/javascript')
         stream |= Transformer('//head').prepend(script)
         stream |= Transformer(
             '//div[@id="content"]/div[@id="ticket"]/div[@class="description"]/h3'
         ).after(button)
         stream |= Transformer(
             '//div[@id="content"]/div/div[@id="changelog"]/div[@class="change"]/h3'
         ).after(button)
         add_stylesheet(req, 'translate/translate.css')
         add_script_data(req, {'googleApiKey': self.googleApiKey})
         add_script_data(req, {'sessionLanguage': req.locale.language})
         add_script(req, 'translate/translate.js')
     return stream
 def _make_graph(self, req, repos, info):
     # Generate graph data
     graph = {}
     threads, vertices, columns = \
         make_log_graph(repos, (item['rev'] for item in info))
     graph.update(threads=threads, vertices=vertices, columns=columns,
                  colors=self.graph_colors,
                  line_width=0.04, dot_radius=0.1)
     add_script(req, 'revisiongraph/js/excanvas.js')
     add_script(req, 'revisiongraph/js/log_graph.js')
     add_script_data(req, {'graph': graph})
     
     script = Markup("//<![CDATA[") + """
     jQuery(document).ready(function($) {
       $('th.trac-graph, td.trac-graph').show();
       var canvas = $('""" + Markup("<canvas>") + """').css({width: '%dem',
                                       height: '%dem'})
                                 .appendTo('td.trac-graph')[0];
       canvas.width = $(canvas).width();
       canvas.height = $(canvas).height();
       if (typeof(G_vmlCanvasManager) != 'undefined')
         canvas = G_vmlCanvasManager.initElement(canvas);
       $.paintLogGraph(graph, canvas);
     });
     """ % (graph['columns'] * 2, len(info) * 2) + Markup("//]]>")
     
     th = tag.th('Graph', class_='trac-graph')
     td = tag.td(class_='trac-graph', rowspan='%d' % len(info))
     
     script_filter = Transformer('//head').append(tag.script(script, type="text/javascript"))
     table_filter = Transformer('//table[@class="listing chglist"]').attr('class', 'listing chglist trac-graph')
     th_filter = Transformer('//table/thead/tr/th[@class="diff"]').before(th)
     td_filter = Transformer('//table/tbody/tr[1]/td[@class="diff"]').before(td)
     
     return [script_filter, table_filter, th_filter, td_filter]
示例#6
0
 def script():
     from genshi.builder import tag
     data = getattr(req, '_tracdragdrop_data')
     text = '\n'.join([
         'var %s = %s;' % (name, to_json(val))
         for name, val in data.iteritems()])
     return tag.script(text, type='text/javascript')
示例#7
0
    def filter_stream(self, req, method, filename, stream, data):
        # Add Stylesheet here, so that the ticket page gets it too :)
        add_stylesheet(req, "clients/clients.css")

        newticket = req.path_info.startswith('/newticket')
        if req.path_info.startswith('/ticket/') or newticket:
            setdefaultrate = ''
            if newticket:
              setdefaultrate = "$('#field-client').trigger('change');"
            
            script = StringIO()
            script.write("""
              $(document).ready(function() {
                $('#field-client').change(function() {
                  """);
            script.write('var clientrates = new Array();')
            for client in Client.select(self.env):
                script.write('clientrates["%s"] = %s;' % (client.name, client.default_rate or '""'))
            script.write("""
                  try { $('#field-clientrate').attr('value', clientrates[this.options[this.selectedIndex].value]); }
                  catch (er) { }
                });
                %s
             });""" % setdefaultrate);
            stream |= Transformer('.//head').append(tag.script(script.getvalue(), type_='text/javascript'))
        return stream
示例#8
0
 def filter_stream(self, req, method, filename, stream, data):
     if filename == 'ticket.html':
         ticket = data.get('ticket')
         if ticket and ticket.exists and \
                req.session.get(self.session_field, 'True') == 'True':
             filter_ = Transformer(
                 '//script[contains(@src, "jquery.js")]')
             return stream | filter_.after(
                 tag.script(
                     type="text/javascript",
                     src=self.env.href('chrome', 'ac', 'js', 'jquery.form.js'))) \
                     | filter_.after(
                 tag.script(
                     type="text/javascript",
                     src=self.env.href('chrome', 'ac', 'js', 'comments.js')))
     return stream
示例#9
0
    def embed_player(self, formatter, url, query, style):
        query_dict = xform_query(query)
        set_default_parameters(
            query_dict,
            _EMBED_FLOWPLAYER_DEFAULT_PARAMETERS
        )

        player_id = self._generate_player_id()
        swf = pathjoin(formatter.href.chrome(), EMBED_PATH_FLOWPLAYER['swf'])
        style.pop('width')  # use adaptiveRatio for player-size
        style.pop('height')  # use adaptiveRatio for player-size
        attrs = {
            'id': player_id,
            'data-swf': swf,
            'style': xform_style(style),
        }
        return tag.div(
            tag.video([
                tag.source(type=mimetypes.guess_type(url)[0], src=url),
                tag.script("""
                    $(function() {
                        $('#%s').flowplayer(%s);
                    });
                """ % (player_id, to_json(query_dict))
                ),
            ]),
            **attrs
        )
示例#10
0
 def expand_macro(self, formatter, name, content):
     content = content.strip()
     if not content.isdigit():
         return system_message('Invalid Ohloh project ID',
                               '%s is not a number' % content)
     return tag.script('',
                       src=self.SCRIPT_LOCATION % content,
                       type='text/javascript')
示例#11
0
 def script():
     from genshi.builder import tag
     data = getattr(req, '_tracdragdrop_data')
     text = '\n'.join([
         'var %s = %s;' % (name, to_json(val))
         for name, val in data.iteritems()
     ])
     return tag.script(text, type='text/javascript')
示例#12
0
    def expand_macro(self, formatter, name, content):
        if content and content.strip():

            def repl(match):
                return self._quote[match.group(0)]

            return tag.script(self._quote_re.sub(repl, content),
                              type='WaveDrom')
示例#13
0
 def load_map(self, locations, kml=None):
     """JS map for issues"""
     options = '{kml: %s}' % (kml and '"%s"' % kml or 'null')
     script = """$(document).ready(function() {
   var locations = %s;
   map_locations(locations, %s);
   })""" % (simplejson.dumps(locations), options)
     return tag.script(Markup(script), **{'type': 'text/javascript'})
示例#14
0
 def load_map(self, locations, kml=None):
     """JS map for issues"""
     options = '{kml: %s}' % (kml and '"%s"' % kml or 'null')
     script = """$(document).ready(function() {
   var locations = %s;
   map_locations(locations, %s);
   })""" % (simplejson.dumps(locations), options)
     return tag.script(Markup(script), **{'type': 'text/javascript'})
示例#15
0
 def filter_stream(self, req, method, filename, stream, data):
     self.log.debug("TicketWebUiAddon executing")
     if not filename == 'ticket.html':
         #self.log.debug("TicketWebUiAddon not emitting ticket javascript because we are not on ticket.html")
         return stream
     stream = stream | Transformer('//div[@id="banner"]').before(
         tag.script(type="text/javascript",
                    src=req.href.chrome("Billing", "ticket.js"))())
     return stream
示例#16
0
    def _expand_view_topic(self, formatter, name, content):
        self.log.debug("Rendering ViewTopic macro...")

        # Check permission
        if not formatter.perm.has_permission('DISCUSSION_VIEW'):
            return

        # Determine topic subject
        page_name = formatter.req.path_info[6:] or 'WikiStart'
        subject = content or page_name

        # Create request context.
        context = Context.from_request(formatter.req)
        context.realm = 'discussion-wiki'

        # Get database access.
        db = self.env.get_db_cnx()
        context.cursor = db.cursor()

        # Get API component.
        api = self.env[DiscussionApi]

        # Get topic by subject
        try:
            id = int(subject)
            topic = api.get_topic(context, id)
        except:
            topic = api.get_topic_by_subject(context, subject)
        self.log.debug('subject: %s' % (subject,))
        self.log.debug('topic: %s' % (topic,))

        # Prepare request and resource object.
        if topic:
            context.req.args['topic'] = topic['id']
            context.resource = Resource('discussion', 'topic/%s' % (topic['id']
              ,))

        # Process discussion request.
        template, data = api.process_discussion(context)

        # Return rendered template.
        data['discussion']['mode'] = 'message-list'
        data['discussion']['page_name'] = page_name
        if context.redirect_url:
            # Generate HTML elements for redirection.
            href = context.req.href(context.redirect_url[0]) + \
              context.redirect_url[1]
            self.log.debug("Redirecting to %s" % (href))
            return tag.div(tag.strong('Redirect: '),
              ' This page redirects to ', tag.a(href, href = href),
              tag.script("window.location = '" + context.req.href('discussion',
              'redirect', redirect_url = href) + "'", language = "JavaScript"),
              class_ = "system-message")
        else:
            # Render template.
            return to_unicode(Chrome(self.env).render_template(formatter.req,
              template, data, 'text/html', True))
示例#17
0
 def filter_stream(self, req, method, filename, stream, data):
     self.log.debug("TicketWebUiAddon executing")
     if not filename == 'ticket.html':
         return stream
     stream = stream | Transformer('//div[@id="banner"]').before(
         tag.script(type="text/javascript",
                    src=req.href.chrome("timingandestimation", "ticket.js"))()
         )
     return stream
示例#18
0
    def filter_stream(self, req, method, filename, stream, formdata):
        if (filename == 'ticket.html'):
            add_stylesheet(req, 'multiselectlist/css/jquery-ui.css')
            add_stylesheet(req, 'multiselectlist/css/jquery.multiselect.css')
            add_script(req,
                       'multiselectlist/js/jquery-ui-1.8.16.custom.min.js')
            add_script(req, 'multiselectlist/js/jquery.multiselect.min.js')

            for item in self.multilist:
                values = self.env.config.get('multiselectlist',
                                             '%s.values' % item)
                if values:
                    key = 'field_%s' % unicode(item)
                    # 既存のチケットの場合はDBに格納されている値を取得する
                    inputvalues = []
                    if key in req.args:
                        # チケット登録時のバリデーションで引っかかった場合
                        # なお、DBに保管されている値より優先しなければならない
                        inputvalues = req.args.get(key)
                    elif req.path_info.startswith('/ticket'):
                        ticketno = req.path_info[8:]
                        db = self.env.get_db_cnx()
                        cursor = db.cursor()
                        sql = "select value from ticket_custom where ticket=%s and name='%s'" % (
                            ticketno, item)
                        cursor.execute(sql)
                        row = cursor.fetchone()
                        if row and row[0]:
                            inputvalues = row[0].split(',')

                    self.env.log.info(inputvalues)
                    value = values.split(',')
                    xpath = '//input[@id="field-%s"]' % item
                    # input要素をselect/option要素に置き換える。
                    # タグの繰り返しを行う場合は、配列で指定すればいいようだ。

                    script = """
jQuery(function(){
  jQuery("#field-%s").multiselect({
    selectedList: 3
  });
});
""" % item

                    stream |= Transformer(xpath).replace(
                        tag.select([
                            tag.option(v, selected=(v in inputvalues or None))
                            for v in value
                        ],
                                   id='field-%s' % item,
                                   name='field_%s' % item,
                                   size='%d' % len(value),
                                   multiple='true'))
                    stream |= Transformer('//head').append(
                        tag.script(script, type="text/javascript"))
        return stream
示例#19
0
 def filter_stream(self, req, method, filename, stream, data):
     self.log.debug("TicketWebUiAddon executing") 
     if not filename == 'ticket.html':
         #self.log.debug("TicketWebUiAddon not emitting ticket javascript because we are not on ticket.html")
         return stream
     stream = stream | Transformer('//div[@id="banner"]').before(
         tag.script(type="text/javascript", 
                    src=req.href.chrome("Billing", "ticket.js"))()
         )
     return stream
示例#20
0
 def filter_stream(self, req, method, filename, stream, data):
     if filename == 'query.html':
         filter_script = Transformer('//script[contains(@src, "jquery.js")]')
         filter_query = Transformer('table[@class="listing tickets"]/.')
         return stream | filter_script.after(
             tag.script(
                 type="text/javascript",
                 src=self.env.href('chrome', 'aq', 'js', 'query.js'))) \
                 | filter_query.prepend('<!-- Hello -->')
     return stream
示例#21
0
 def filter_stream(self, req, method, filename, stream, data):
     if filename == 'query.html':
         filter_script = Transformer(
             '//script[contains(@src, "jquery.js")]')
         filter_query = Transformer('table[@class="listing tickets"]/.')
         return stream | filter_script.after(
             tag.script(
                 type="text/javascript",
                 src=self.env.href('chrome', 'aq', 'js', 'query.js'))) \
                 | filter_query.prepend('<!-- Hello -->')
     return stream
示例#22
0
 def _create_twitter_button(self, url, locale):
     return [
         tag.a('Tweet',
               href='//twitter.com/share',
               class_='twitter-share-button',
               data_url=url, data_counturl=url,
               data_lang=locale or None,
               data_count=self._twitter_data_count),
         tag.script(type='text/javascript',
                    src='//platform.twitter.com/widgets.js'),
     ]
示例#23
0
    def expand_macro(self, formatter, name, content):
        req = formatter.req
        query_string = TicketQueryMacro.parse_args(content)[0]

        kwargs = dict([item.split('=') for item in content.split(',')[1:]])

        try:
            query = Query.from_string(self.env, query_string)
        except QuerySyntaxError as e:
            raise MacroError(e)

        try:
            tickets = query.execute(req)
        except QueryValueError as e:
            raise MacroError(e)

        # Formats above had their own permission checks, here we need to
        # do it explicitly:

        tickets = [t for t in tickets
                   if 'TICKET_VIEW' in req.perm(self.realm, t['id'])]

        tickets = map(lambda x: Ticket(self.env, x['id']), tickets)

        schedule_info = {'test': TicketScheduleSystem(self.env).get_schedule(tickets)}

        add_script(req, 'ticketrelation/js/bundle.js')
        add_stylesheet(req, 'ticketrelation/css/schedule.css')

        random_id = str(random.randint(0, 10000))

        config = {
            'url': req.base_url,
            'startDate': kwargs.get('startdate', None),
            'finishDate': kwargs.get('finishdate', None),
            'showUnavailable': kwargs.get('showunavailable', 1)
        }

        return tag.div(tag.div(
            tag.schedule(**{':schedule': 'schedule', ':config': 'config'}), class_='schedule_container', id='schedule_container_' + random_id),
            tag.script("""         
                $(window).load(function() {
                    var data = %s;
                    var config = %s;
                    var app = new window.Vue({
                        el: '#schedule_container_%s',
                        data: {
                            schedule: data,
                            config: config,
                        }
                    });
                });""" % (json.dumps(schedule_info, cls=DateTimeEncoder), json.dumps(config, cls=DateTimeEncoder), random_id))
        )
示例#24
0
 def _create_twitter_button(self, url, locale):
     return [
         tag.a('Tweet',
               href='//twitter.com/share',
               class_='twitter-share-button',
               data_url=url,
               data_counturl=url,
               data_lang=locale or None,
               data_count=self._twitter_data_count),
         tag.script(type='text/javascript',
                    src='//platform.twitter.com/widgets.js'),
     ]
示例#25
0
    def filter_stream(self, req, method, filename, stream, data):
        if not _is_wysiwyg_enabled(filename, self.templates):
            return stream

        options = {}
        if filename == 'ticket.html':
            options['escapeNewlines'] = _preserve_newlines(self.env)

        if options:
            text = 'var _tracwysiwyg = %s' % _to_json(options)
            stream |= Transformer('//head').append(tag.script(text, type='text/javascript'))

        return stream
示例#26
0
 def _create_hatena_bookmark_button(self, url, locale):
     href = '//b.hatena.ne.jp/entry/'
     if url:
         href += url.replace('#', '%23')
     return [
         tag.a(tag.img(src='//b.st-hatena.com/images/entry-button/button-only.gif',
                       alt=u'このエントリーをはてなブックマークに追加',
                       width='20', height='20', style='border:none'),
               href=href, class_='hatena-bookmark-button',
               data_hatena_bookmark_layout=self._hatena_bookmark_layout,
               title=u'このエントリーをはてなブックマークに追加'),
         tag.script(type='text/javascript', charset='utf-8', async='async',
                    src='//b.st-hatena.com/js/bookmark_button_wo_al.js'),
     ]
示例#27
0
    def filter_stream(self, req, method, filename, stream, data):
        if not _is_wysiwyg_enabled(filename, self.templates):
            return stream

        options = {}
        if filename == 'ticket.html':
            options['escapeNewlines'] = _preserve_newlines(self.env)

        if options:
            text = 'var _tracwysiwyg = %s' % _to_json(options)
            stream |= Transformer('//head').append(
                tag.script(text, type='text/javascript'))

        return stream
示例#28
0
 def _parse_params(self):
     self.metatags = [tag.meta(charset=self.document.settings.output_encoding)]
     self.stylesheets = []
     stylesheets = self.document.settings.stylesheet or []
     for href in stylesheets:
         self.stylesheets.append(tag.link(rel='stylesheet', href=href))
     self.scripts = []
     scripts = self.document.settings.script or []
     for src, attributes in scripts:
         script = tag.script(src=src)
         if attributes:
             script = script(**{attributes: attributes})
         self.scripts.append(script)
     return
示例#29
0
    def expand_macro(self, formatter, name, content, args=None):
        add_script(formatter.req, 'mathjax/update.js', 'text/javascript')

        # We access this internals directly because it is not possible to use add_script with full/absolute URL
        # http://trac.edgewall.org/ticket/10369
        # We know scripts and scriptset elements are initialized because we called add_script before
        if MATHJAX_URL not in formatter.req.chrome.get('scriptset'):
            formatter.req.chrome.get('scripts').append({
                'href':
                MATHJAX_URL + '?delayStartupUntil=configured',
                'type':
                'text/javascript',
            })
            formatter.req.chrome.get('scriptset').add(MATHJAX_URL)

        # We load configuration afterwards, as we have delay it with delayStartupUntil and we call MathJax.Hub.Configured here
        # We do this because having text/x-mathjax-config config blocks outside the head does not seem to work
        add_script(formatter.req, 'mathjax/config.js', 'text/javascript')

        if args is None:  # Called as macro
            return tag.script(Markup(content), type_="math/tex")
        else:  # Called as processor
            return tag.script(Markup(content), type_="math/tex; mode=display")
示例#30
0
 def jsconfig_tag(self):
     if self.js_config is None:
         return None
     if json is None:
         if 'theme' in self.js_config:
             msg = 'simplejson is not available, can not set reCAPTCHA ' + \
                   'theme. Please install simplejson.'
             self.log.error(msg)
         else:
             msg = 'simplejson is not available so the reCAPTCHA widget ' + \
                   'can not switch to the user\'s language.'
             self.log.debug(msg)
         return None
     js_string = 'RecaptchaOptions = %s;' % json.dumps(self.js_config)
     return tag.script(js_string, type='text/javascript')
    def _enable_treesearch_for_page(self, req, stream, fields):
        project_name = req.environ.get('SCRIPT_NAME')

        add_script(req, 'treesearch/js/treesearch.js')
        add_stylesheet(req, 'treesearch/css/treesearch.css')
        add_script_data(req,(('selector',','.join(fields)),('params',{'SERVER_URL': project_name + '/diff'})))

        stream = stream | Transformer('head').append(tag.script('''
               jQuery(document).ready(function() {
                 jQuery(selector).each(function() {
                   $(this).addClass('treesearch');
                   $(this).tree(params);
                 });
               });'''))
        return stream
示例#32
0
 def filter_stream(self, req, method, filename, stream, data):
     if req.path_info.startswith('/ticket'):
         button = tag.div(tag.input(type="submit", title=_("Translate to %s") % req.locale.get_display_name(), value=_("Translate"), forward=_("Translate"), backward=_("Untranslate"), working=_("Working"), name="translate", class_="translate"))
         button(class_="inlinebuttons")
         script = tag.script('');
         script(src = 'https://www.google.com/jsapi?key='+self.googleApiKey)
         script(type = 'text/javascript')
         stream |= Transformer('//head').prepend(script)
         stream |= Transformer('//div[@id="content"]/div[@id="ticket"]/div[@class="description"]/h3').after(button)
         stream |= Transformer('//div[@id="content"]/div/div[@id="changelog"]/div[@class="change"]/h3').after(button)
         add_stylesheet(req, 'translate/translate.css')
         add_script_data(req, {'googleApiKey': self.googleApiKey})
         add_script_data(req, {'sessionLanguage': req.locale.language})
         add_script(req, 'translate/translate.js')
     return stream
示例#33
0
 def _parse_params(self):
     self.metatags = [
         tag.meta(charset=self.document.settings.output_encoding)
     ]
     self.stylesheets = []
     stylesheets = self.document.settings.stylesheet or []
     for href in stylesheets:
         self.stylesheets.append(tag.link(rel='stylesheet', href=href))
     self.scripts = []
     scripts = self.document.settings.script or []
     for src, attributes in scripts:
         script = tag.script(src=src)
         if attributes:
             script = script(**{attributes: attributes})
         self.scripts.append(script)
     return
    def filter_stream(self, req, method, filename, stream, formdata):
        if (filename == 'ticket.html'):
            add_stylesheet(req, 'multiselectlist/css/jquery-ui.css')
            add_stylesheet(req, 'multiselectlist/css/jquery.multiselect.css')
            add_script(req, 'multiselectlist/js/jquery-ui-1.8.16.custom.min.js')
            add_script(req, 'multiselectlist/js/jquery.multiselect.min.js')

            for item in self.multilist:
                values = self.env.config.get('multiselectlist', '%s.values' % item)
                if values:
                    key = 'field_%s' % unicode(item)
                    # 既存のチケットの場合はDBに格納されている値を取得する
                    inputvalues = []
                    if key in req.args:
                        # チケット登録時のバリデーションで引っかかった場合
                        # なお、DBに保管されている値より優先しなければならない
                        inputvalues = req.args.get(key)
                    elif req.path_info.startswith('/ticket'):
                        ticketno = req.path_info[8:]
                        db = self.env.get_db_cnx()
                        cursor = db.cursor()
                        sql = "select value from ticket_custom where ticket=%s and name='%s'" % (ticketno, item)
                        cursor.execute(sql)
                        row = cursor.fetchone()
                        if row and row[0]:
                            inputvalues = row[0].split(',')

                    self.env.log.info(inputvalues)
                    value = values.split(',')
                    xpath = '//input[@id="field-%s"]' % item
                    # input要素をselect/option要素に置き換える。
                    # タグの繰り返しを行う場合は、配列で指定すればいいようだ。

                    script = """
jQuery(function(){
  jQuery("#field-%s").multiselect({
    selectedList: 3
  });
});
""" % item

                    stream |= Transformer(xpath).replace(
                        tag.select(
                            [tag.option(v, selected=(v in inputvalues or None)) for v in value],
                            id='field-%s' % item, name='field_%s' % item, size='%d' % len(value), multiple='true'))
                    stream |= Transformer('//head').append(tag.script(script, type="text/javascript"))
        return stream
 def widget_fix(self, tag_id):
     ""
     js = '''
         var factoid = jQuery('#%(tag_id)s');
         var factoidDivElements = factoid.find('div');
         
         // remove background color
         var factoidWithBackgroundColor = function(index){ return 'transparent' !== jQuery(this).css('background-color'); };
         factoidDivElements.filter(factoidWithBackgroundColor).css('background-color', 'transparent');
         
         // remove round corners
        factoidDivElements.filter(function() { return "none" !== $(this).css('background-image') }).remove()
        
        // ensure all links have the right color
        factoid.find('a').css({'color': null}); 
     ''' % dict(tag_id=tag_id)
     return tag.script(js, type='text/javascript')
示例#36
0
    def filter_stream(self, req, method, filename, stream, data):
        if (filename <> 'ticket.html'):
            return stream
       
        keywords = self.config.getlist('keywordsuggest','keywords')
        if not keywords:
            self.log.debug('List of keywords not found in trac.ini. '\
                           'Plugin keywordsuggest disabled.')
            return stream

        keywords = ','.join(("'%s'" % keyword for keyword in keywords))
        mustmatch = 'mustMatch: true,'
        if not self.config.getbool('keywordsuggest','mustmatch'):
            mustmatch = ""
        sep = self.config.get('keywordsuggest','multipleseparator', '')[1:-1] or ', '
        matchcontains = 'matchContains: true,'
        if not self.config.getbool('keywordsuggest','matchcontains',True):
            matchcontains = ""

        # inject transient part of javascript directly into ticket.html template
        js = """
        $(function($) {
          var sep = '%s'
          $('#field-keywords').autocomplete([%s], {multiple: true, %s
                                            %s multipleSeparator: sep, autoFill: true}); 
          $("form").submit(function() {
              // remove trail separator if any
              keywords = $("input#field-keywords").attr('value')
              if (keywords.lastIndexOf(sep) + sep.length == keywords.length) {
                  $("input#field-keywords").attr('value', keywords.substring(0, keywords.length-sep.length))
              }
          });
        });""" % (sep, keywords, matchcontains, mustmatch)
        stream = stream | Transformer('.//head').append \
                          (tag.script(Markup(js), type='text/javascript'))

        # turn keywords field label into link to wiki page
        helppage = self.config.get('keywordsuggest','helppage')
        if helppage:
            link = tag.a(href='wiki/%s' % helppage, target='blank')
            if not self.config.getbool('keywordsuggest','helppage.newwindow',
                                       'false'):
                link.attrib -= 'target'
            stream = stream | Transformer\
                         ('//label[@for="field-keywords"]/text()').wrap(link)
        return stream
示例#37
0
  def get_ajax(self, macroenv, req, content):
    macroenv.tracenv.log.debug("AJAX: %s" % (content,) )
    
    myhash = hashlib.md5(content).hexdigest()
    ajax_url = "/projectplan_service/%s" % (urllib.quote_plus(content),)
    
    return tag.div(
      tag.div(
        tag.div(
	  tag.a(tag.img(
		src="%s/%s" % (macroenv.tracreq.href.chrome( 'projectplan', macroenv.PPConstant.RelDocPath ), 'loading.gif' ), 
		style='display:none;margin-right:2ex;margin-top:3ex;',
		title='computing projectplan report'
	      ),
	      tag.span("project report is loading"),
	      href=ajax_url,
	      style='padding:3ex;text-align:center;'
	  ),
          id="%s_inner" % myhash,
          style="height:8ex;"
        ),
        id=myhash,
        style="height:8ex"
        ),
      tag.script('''
        $(document).ready(function(){
	  $.ajax({
	      url: "%s",
	      cache: false,
	      beforeSend: function(){
	        $("#%s img").show();
	      },
	      success: function(data){
	        $("#%s").hide().after(data);
	        ppAddTooltipWrapper("#%s");
	      },
	      error: function(jqXHR, textStatus, errorThrown){
	        $("#%s a").first().html("Error: report (of ProjectPlan) could not be rendered.").css({padding:"0",margin:"auto"});
	        $("#%s").addClass("system-message").css({height:"auto"});
	        $("#%s_inner").css({height:"auto"});
	      }
	  });
	});
        ''' % (ajax_url, myhash, myhash, myhash, myhash, myhash, myhash )) 
    )
示例#38
0
 def visit_math_block(self, node):
     '''
     Only MathJax support
     '''
     math_code = node.astext()
     math_env = pick_math_environment(math_code)
     if 'align' in math_env:
         template = '\\begin{%s}\n%s\n\\end{%s}' % (math_env, math_code, math_env)
         elem = tag.div(template)
     else:  # equation
         template = '\(%s\)' % math_code
         elem = tag.span(template)
     elem(class_='math')
     self.context.append(elem)
     if not getattr(self, 'already_has_math_script', None):
         src = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
         self.scripts.append(tag.script(src=src))
         self.already_has_math_script = True
     raise nodes.SkipNode
示例#39
0
文件: util.py 项目: league/gauz
 def obfuscate(self, clearText,
               format='<a href="mailto:%s">%s</a>',
               noscript='%s',
               at = u' § ', dot = u' · '):
     humanText = clearText.replace('@', at).replace('.', dot)
     valid, ignore = self.randomlyPartition()
     obfuText = self.buildObfuscatedString(humanText, valid, ignore)
     expr = '"' + obfuText + '"'
     expr += '.replace(/([%s](.)|[%s].)/ig,"$2")' % (valid, ignore)
     expr += '.replace(/%s/g, "@")' % at
     expr += '.replace(/%s/g, ".")' % dot
     var = 's%06x' % random.randrange(0x1000000)
     format = self.jsQuote(format, var)
     t = tag(tag.script('var ', var, ' = ', expr, ';\n',
                        'document.write(', Markup(format), ');\n',
                        type='text/javascript'))
     if noscript:
         t = t(tag.noscript(noscript.replace('%s', humanText)))
     return t
 def widget_fix(self, tag_id):
     ""
     js = '''
         var widget = jQuery('#%(tag_id)s');
         
         // trac's wiki page/h3 has a negative margin-left
         widget.find('h3').css({'margin-left': '-10px'});
         
         // #div.gadget div.main' gets an additional margin-left which looks
         // bad - however it's done with an addition <style> tag so we can't
         // remove the rule itself. Instead this will make sure that the rule
         // does not apply anymore
         widget.find('div.gadget div.main').removeClass('main');
         
         // the Ohloh logo floats all the way to the right, so we just set
         // a width
         widget.find('div.gadget').css({'width': '20em'});
     ''' % dict(tag_id=tag_id)
     return tag.script(js, type='text/javascript')
示例#41
0
 def _parse_params(self):
     self.metatags = [tag.meta(charset=self.document.settings.output_encoding)]
     self.stylesheets = []
     stylesheets = self.document.settings.stylesheet or []
     for href in stylesheets:
         self.stylesheets.append(tag.link(rel='stylesheet', href=href))
     stylesheets_inline = []
     for path in (self.document.settings.stylesheet_inline or []):
         with open(path) as f:
             stylesheets_inline.append(f.read())
     if stylesheets_inline:
         self.stylesheets.append(tag.style(Markup(''.join(stylesheets_inline))))
     self.scripts = []
     scripts = self.document.settings.script or []
     for src, attributes in scripts:
         script = tag.script(src=src)
         if attributes:
             script = script(**{attributes: attributes})
         self.scripts.append(script)
     return
示例#42
0
 def _create_hatena_bookmark_button(self, url, locale):
     href = '//b.hatena.ne.jp/entry/'
     if url:
         href += url.replace('#', '%23')
     return [
         tag.a(tag.img(
             src='//b.st-hatena.com/images/entry-button/button-only.gif',
             alt=u'このエントリーをはてなブックマークに追加',
             width='20',
             height='20',
             style='border:none'),
               href=href,
               class_='hatena-bookmark-button',
               data_hatena_bookmark_layout=self._hatena_bookmark_layout,
               title=u'このエントリーをはてなブックマークに追加'),
         tag.script(type='text/javascript',
                    charset='utf-8',
                    async='async',
                    src='//b.st-hatena.com/js/bookmark_button_wo_al.js'),
     ]
示例#43
0
 def visit_math_block(self, node):
     '''
     Only MathJax support
     '''
     math_code = node.astext()
     math_env = pick_math_environment(math_code)
     if 'align' in math_env:
         template = '\\begin{%s}\n%s\n\\end{%s}' % (math_env, math_code,
                                                    math_env)
         elem = tag.div(template)
     else:  # equation
         template = '\(%s\)' % math_code
         elem = tag.span(template)
     elem(class_='math')
     self.context.append(elem)
     if not getattr(self, 'already_has_math_script', None):
         src = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
         self.scripts.append(tag.script(src=src))
         self.already_has_math_script = True
     raise nodes.SkipNode
示例#44
0
    def filter_stream(self, req, method, filename, stream, data):
        if filename == "ticket.html" and 'ticket' in data:
            ticket = data['ticket']

            if ticket.id > 0 and self._have_schedule(ticket):

                add_stylesheet(req, 'ticketrelation/css/schedule.css')

                schedule = self._get_schedule_info(ticket)

                stream |= Transformer('//div[@id="ticket"]').after(
                    tag.div(
                        tag.h3(
                            tag.a('Schedule', id='schedule_label', href='#schedule_label'),
                        class_='foldable'),
                        tag.div(tag.schedule(**{':schedule': 'schedule', ':config': 'config'}), class_='schedule_container', id='schedule_container'),
                    id='schedule')
                )

                config = {
                    'url': req.base_url,
                    'startDate': None,
                    'finishDate': None,
                    'showUnavailable': 1
                }

                stream |= Transformer('//body').append(tag.script("""
                    $(window).load(function() {
                        var data = %s;
                        var config = %s;
                        var app = new Vue({
                            el: '#schedule_container',
                            data: {
                                schedule: data,
                                config: config,
                            }
                        });
                    });
                """ % (json.dumps(schedule, cls=DateTimeEncoder), json.dumps(config, cls=DateTimeEncoder))))

        return stream
示例#45
0
    def filter_stream(self, req, method, filename, stream, data):
        """Add javascript to the ticket pages that makes an ajax request whenever
        a field changes so that the rules for hidden fields can be processed at the
        server side without and be effected without a page reload."""
        if not req.path_info.startswith(('/newticket', '/ticket')):
            return stream

        address = tag.script(type="text/javascript")
        address.append("function getTracURL() { return '")
        address.append(req.base_url + AJAX_URL + "'; }")

        stream |= Transformer('.//head').append(address)

        # For some reason there isn't a status field on the ticket page, only the newticket page
        # Add it in so validation rules involving the status work
        if req.path_info.startswith('/ticket') and 'ticket' in data:
            status = tag.input(type="hidden", name="field_status", value=data['ticket'].values['status'])
            stream |= Transformer(".//form[@id='propertyform']").append(status)

        add_script(req, "ticketvalidation/js/RuleUpdate.js")
        return stream
示例#46
0
    def get_ajax(self, macroenv, req, content):
        macroenv.tracenv.log.debug("AJAX: %s" % (content, ))

        myhash = hashlib.md5(content).hexdigest()
        ajax_url = "/projectplan_service/%s" % (urllib.quote_plus(content), )

        return tag.div(
            tag.div(tag.div(tag.a(tag.img(
                src="%s/%s" % (macroenv.tracreq.href.chrome(
                    'projectplan',
                    macroenv.PPConstant.RelDocPath), 'loading.gif'),
                style='display:none;margin-right:2ex;margin-top:3ex;',
                title='computing projectplan report'),
                                  tag.span("project report is loading"),
                                  href=ajax_url,
                                  style='padding:3ex;text-align:center;'),
                            id="%s_inner" % myhash,
                            style="height:8ex;"),
                    id=myhash,
                    style="height:8ex"),
            tag.script('''
        $(document).ready(function(){
	  $.ajax({
	      url: "%s",
	      cache: false,
	      beforeSend: function(){
	        $("#%s img").show();
	      },
	      success: function(data){
	        $("#%s").hide().after(data);
	        ppAddTooltipWrapper("#%s");
	      },
	      error: function(jqXHR, textStatus, errorThrown){
	        $("#%s a").first().html("Error: report (of ProjectPlan) could not be rendered.").css({padding:"0",margin:"auto"});
	        $("#%s").addClass("system-message").css({height:"auto"});
	        $("#%s_inner").css({height:"auto"});
	      }
	  });
	});
        ''' % (ajax_url, myhash, myhash, myhash, myhash, myhash, myhash)))
    def filter_stream(self, req, method, filename, stream, data):
        if req.path_info == '/select_tickets':
            stream |= Transformer('//div[@id="banner"]').remove()
            stream |= Transformer('//div[@id="mainnav"]').remove()
            stream |= Transformer('//div[@id="ctxtnav"]').remove()

        if (filename == "ticket.html"
                or filename == 'ticket_preview.html') and 'ticket' in data:
            ticket = data['ticket']
            trs = TicketRelationSystem(self.env)
            data = {}
            for relation in trs.build_relations().values():
                if relation.ticket_type_a == ticket['type']:
                    stream = self._generate_html(relation,
                                                 relation.relation_type_a, 'a',
                                                 stream, ticket, data)
                elif relation.ticket_type_b == ticket['type']:
                    stream = self._generate_html(relation,
                                                 relation.relation_type_b, 'b',
                                                 stream, ticket, data)

            add_script(req, 'ticketrelation/js/bundle.js')

            stream |= Transformer('//body').append(
                tag.script("""
                (function () {
                var data = %s;
                var app = new Vue({
                    el: '#properties',
                    data: {
                        relation: data,
                    }
                });
                })();
            """ % json.dumps(data)))

        return stream
    def _enable_autocomplete_for_page(self, req, method, filename, stream, data, inputs):
        add_stylesheet(req, 'autocomplete/css/autocomplete.css')
        add_script(req, 'autocomplete/js/jquery.tracautocomplete.js')

        username_completers = list(self._username_completers(req))
        add_script_data(req, {'username_completers': username_completers})
                
        # we could put this into some other URL which the browser could cache?
        #show users from all groups, shown or not, on the members page
        add_script_data(req, {'project_users': self._project_users})

        controls = (self._split_input(input_) for input_ in inputs)
        js = ''.join('$("%s").makeAutocompleteSearch("%s", %s);\n'
                     % (selector, method_ or 'select',
                        options if isinstance(options, basestring)
                        else to_json(options))
                     for selector, method_, options in controls)
                
        stream = stream | Transformer('//head').append(tag.script("""
        jQuery(document).ready(function($) {
        %s
        });
        """ % js,type="text/javascript"))
        return stream
示例#49
0
	def filter_stream(self, req, method, template, stream, data):
		if not (template == 'browser.html' and data.get('dir')):
			if ((not data.get('dir')) and (data.get('path')) and (data.get('path').endswith('.md'))):	# Rendering single markdown file preview
				stream = stream | Transformer("//head/script[not(@src)][1]").after(
					tag.script(
						Markup(
							"jQuery(document).ready(function($) {"
							"  $('#preview').each(function() {"
							"    $(this).html(marked( $(this).children('pre').first().text() ));"
							"  });"
							"});"
						),
						type = "text/javascript"
					)
				)
			return stream

		add_stylesheet(req, 'common/css/code.css')

		repos = data.get('repos') or self.env.get_repository()
		rev = req.args.get('rev', None)

		for entry in data['dir']['entries']:						# Rendering all READMEs in a directory preview
			try:
				if not entry.isdir and entry.name.lower().startswith('readme'):
					node = repos.get_node(entry.path, rev)
					req.perm(data['context'].resource).require('FILE_VIEW')
					mimeview = Mimeview(self.env)
					content = node.get_content()
					mimetype = node.content_type
					divclass = 'searchable'
					if entry.name.lower().endswith('.wiki'):
						mimetype = 'text/x-trac-wiki'
						divclass = 'searchable wiki'
					elif entry.name.lower().endswith('.md'):
						mimetype = 'text/x-markdown'
						divclass = 'searchable markdown'
					if not mimetype or mimetype == 'application/octet-stream':
						mimetype = mimeview.get_mimetype(node.name, content.read(4096)) or mimetype or 'text/plain'
					del content
					self.log.debug("ReadmeRenderer: rendering node %s@%s as %s" % (node.name, str(rev), mimetype))
					output = mimeview.preview_data(
						data['context'],
						node.get_content(),
						node.get_content_length(),
						mimetype,
						node.created_path,
						'',
						annotations = [],
						force_source = False
					)

					if output:
						if isinstance(output['rendered'], Stream):
							#content = output['rendered'].select('./pre/node()')
							#content = output['rendered'].select('./pre')
							content = output['rendered'].select('.')
						else:
							self.log.debug("GOT THERE")
							content = output['rendered']
						insert = tag.div(
							tag.h1(entry.name,
								tag.a(Markup(' &para;'),
									class_ = "anchor",
									href   = '#' + entry.name,
									title  = 'Link to file'
								),
								id_ = entry.name
							),
							tag.div(
								content,
								#xml:space = "preserve",
								class_ = divclass,
								title = entry.name
							),
							class_ = "readme",
							style  = "padding-top: 1em;"
						)
						stream = stream | Transformer("//div[@id='content']/div[@id='help']").before(insert)
			except Exception, e:
				self.log.debug(to_unicode(e))
示例#50
0
    def filter_stream(self, req, method, filename, stream, data):

        if not (filename == 'ticket.html' or
                (self.tags_enabled and filename == 'wiki_edit.html')):
            return stream

        keywords = self._get_keywords_string(req)
        if not keywords:
            self.log.debug(
                "No keywords found. TagInputAutoComplete is disabled.")
            return stream

        matchfromstart = '"^" +'
        if self.matchcontains_opt:
            matchfromstart = ''

        js = """
            jQuery(document).ready(function($) {
                var keywords = [ %(keywords)s ]
                var sep = '%(separator)s'.trim() + ' '
                function split( val ) {
                    return val.split( /%(separator)s\s*|\s+/ );
                }
                function extractLast( term ) {
                    return split( term ).pop();
                }
                $('%(field)s')
                    // don't navigate away from field on tab when selecting
                    // an item
                    .bind( "keydown", function( event ) {
                        if ( event.keyCode === $.ui.keyCode.TAB &&
                             $( this ).data( "autocomplete" ).menu.active ) {
                            event.preventDefault();
                        }
                    })
                    .autocomplete({
                        delay: 0,
                        minLength: 0,
                        source: function( request, response ) {
                            // delegate back to autocomplete, but extract
                            // the last term
                            response( $.ui.autocomplete.filter(
                                keywords, extractLast( request.term ) ) );
                        },
                        focus: function() {
                            // prevent value inserted on focus
                            return false;
                        },
                        select: function( event, ui ) {
                            var terms = split( this.value );
                            // remove the current input
                            terms.pop();
                            // add the selected item
                            terms.push( ui.item.value );
                            // add placeholder to get the comma-and-space at
                            // the end
                            terms.push( "" );
                            this.value = terms.join( sep );
                            return false;
                        }
                    });
            });"""

        # Inject transient part of JavaScript into ticket.html template.
        if req.path_info.startswith('/ticket/') or \
           req.path_info.startswith('/newticket'):
            js_ticket = js % {
                'field': '#field-' + self.field_opt,
                'keywords': keywords,
                'matchfromstart': matchfromstart,
                'separator': self.separator
            }
            stream = stream | Transformer('.//head').append\
                              (builder.script(Markup(js_ticket),
                               type='text/javascript'))

            # Turn keywords field label into link to an arbitrary resource.
            if self.help_opt:
                link = self._get_help_link(req)
                if self.helpnewwindow_opt:
                    link = builder.a(href=link, target='blank')
                else:
                    link = builder.a(href=link)
                stream = stream | Transformer\
                     ('//label[@for="field-keywords"]/text()').wrap(link)

        # Inject transient part of JavaScript into wiki.html template.
        elif self.tags_enabled and req.path_info.startswith('/wiki/'):
            js_wiki = js % {
                'field': '#tags',
                'keywords': keywords,
                'matchfromstart': matchfromstart,
                'separator': self.separator
            }
            stream = stream | Transformer('.//head').append \
                              (builder.script(Markup(js_wiki),
                               type='text/javascript'))
        return stream
示例#51
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content, strict=True)
        try:
            kwargs = string_keys(kwargs)
        except:
            raise TracError('Error #3922, content: %s, args: %s, kwargs: %s',
                            (str(content), str(args), kwargs))

        if len(args) >= 1:
            url = args[0]
        elif len(args) == 0:
            raise TracError('URL to the mindmap at least required.')

        embed_count = getattr(formatter, EMBED_COUNT, 0)
        embed_count += 1
        setattr(formatter, EMBED_COUNT, embed_count)

        if embed_count == 1:
            add_script(formatter.req, 'freemind/js/flashobject.js')

        url = get_absolute_url(url, formatter)
        base = url[:url.rfind('/') + 1]

        #script = '''\
        #    $(document).ready(function() {
        #        $("#flashcontent%(count)02d").mouseover(function() {
        #            document.visorFreeMind%(count)02d.focus();
        #        });
        #
        #        var fo = new FlashObject("%(visor)s", "visorFreeMind%(count)02d", "100%%", "100%%", 6, "#9999ff");
        #
        #        fo.addParam("quality","high");
        #        fo.addParam("bgcolor","#a0a0f0");
        #        fo.addVariable("openUrl","_blank");
        #        fo.addVariable("startCollapsedToLevel","3");
        #        fo.addVariable("maxNodeWidth","200");
        #        fo.addVariable("mainNodeShape","elipse");
        #        fo.addVariable("justMap","false");
        #        fo.addVariable("initLoadFile","%(file)s");
        #        fo.addVariable("defaultToolTipWordWrap",200);
        #        fo.addVariable("offsetX","left");
        #        fo.addVariable("offsetY","top");
        #        fo.addVariable("buttonsPos","top");
        #        fo.addVariable("min_alpha_buttons",20);
        #        fo.addVariable("max_alpha_buttons",100);
        #        fo.addVariable("scaleTooltips","false");
        #        fo.addVariable("baseImagePath","%(base)s");
        #        fo.addVariable("CSSFile","%(css)s");
        #        //fo.addVariable("toolTipsBgColor","0xa0a0f0");
        #        //fo.addVariable("genAllShots","true");
        #        //fo.addVariable("unfoldAll","true");
        #        fo.write("flashcontent%(count)02d");
        #    });
        #''' % {
        #    'count': embed_count,
        #    'visor': get_absolute_url('htdocs://freemind/swf/visorFreemind.swf', formatter),
        #    'file': url,
        #    'base': base,
        #    'css': get_absolute_url('htdocs://freemind/css/flashfreemind.css', formatter),
        #}

        script = '''\
            $(document).ready(function() {
                $("#flashcontent%(count)02d").mouseover(function() {
                    document.visorFreeMind%(count)02d.focus();
                });
            });
            
            // url: %(url)s
            // base: %(base)s
            
            
        ''' % {
            'count': embed_count,
            'url': url,
            'base': base
        }

        flash_dict = {
            'openUrl': '_blank',
            'initLoadFile': url,
            'startCollapsedToLevel': '3',
            'defaultToolTipWordWrap': '200',
            'baseImagePath': base,
            'min_alpha_buttons': '20',
            'max_alpha_buttons': '100'
        }

        flash_vars = '&'.join(
            ['%s=%s' % (k, v) for k, v in flash_dict.items()])

        embed = tag.embed(type='application/x-shockwave-flash',
                          src=get_absolute_url(
                              'htdocs://freemind/swf/visorFreemind.swf',
                              formatter),
                          id='visorFreeMind%02d' % embed_count,
                          bgcolor='#ffffff',
                          quality='high',
                          flashvars=flash_vars,
                          align='middle',
                          height='100%',
                          width='100%')

        # Debugging.
        if 'debug' in args:
            import os
            import datetime

            output = "FreemindMacro Debug Log\n"\
                     "=======================\n\n"\
                     "time: %(time)s\n"\
                     "version: %(version)s\n"\
                     "content: %(content)s\n"\
                     "args: %(args)s\n"\
                     "kwargs: %(kwargs)s\n"\
                     "formatter.href.base: %(base)s\n"\
                     "script: \n\n"\
                     "%(script)s" % {

                'time': datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ'),
                'version': __version__,
                'content': content,
                'args': str(args),
                'kwargs': str(kwargs),
                'base': str(formatter.href.base),
                'script': script
            }

            return tag.pre(
                output,
                style='border: 2px dashed red; padding: 5px; background: #eee;'
            )

        style_dict = xform_style(kwargs.get('style', ''))

        width = kwargs.pop('width', style_dict.get('width', '800px'))
        height = kwargs.pop('height', style_dict.get('height', '600px'))

        style_dict['border'] = style_dict.get('border', '1px solid #cccccc;')
        style_dict['margin'] = style_dict.get('margin', '0 auto')
        style_dict['width'] = width
        style_dict['height'] = height

        kwargs['style'] = xform_style(style_dict)

        # You can't touch this...
        kwargs.pop('id', None)

        if 'class' in kwargs:
            kwargs['class_'] = kwargs.pop('class')

        tags = []
        #tags.append(tag.div('Flash plugin or JavaScript are turned off. Activate both and reload to view the mindmap.',
        #                    id='flashcontent%02d' % embed_count, **kwargs))

        tags.append(
            tag.div(embed, id='flashcontent%02d' % embed_count, **kwargs))
        tags.append(tag.script(script))

        return ''.join([str(i) for i in tags])
    def _enable_autocomplete_for_page(self, req, stream, inputs):
        add_stylesheet(req, 'autocomplete/css/select2_autocomplete.css')

        #There should never be multiple implementations of IADLDSAutoCompleteProvider
        endpoint = self.autocompleter[0].get_endpoint()
        if endpoint.get('permission') is None or req.perm.has_permission(
                                                    endpoint.get('permission')):
            #Js to initialize select2
            js = ''
            selectors = [str(element + class_) for class_, element in inputs]
            if selectors:
                js += '$("%s").select2({' % ', '.join(selectors)
                js += '''width: "500px",
                        dropdownCssClass: "ui-dialog",'''
                js += 'placeholder: "%s",' % (_('Search known users within' +
                                                   ' this project and users' +
                                                   ' in external sources.'))
                js += 'multiple: true,'
                js += 'minimumInputLength: 2,'
                js += 'tokenSeparators: [",", ";"],'
                js += 'ajax: {'
                js += 'url: "%s",' % req.href(endpoint.get('url'))
                js += '''
        dataType: 'json',
        data: function (term, page) {
            return {
                q: term
            };
          },
          results: function (data, page) {
                return { results: data };
          }
        },
        createSearchChoice: function(term, data) {
            return { id:term, text:term }
        },
        formatResult: userFormatResult,
        formatSelection: userFormatSelection,
        escapeMarkup: function (m) { 
            return m; 
        }'''
                js += '});'
            #Add formatting functions
            stream = stream | Transformer('//head').append(tag.script(Markup('''
function userFormatResult(user) {
    var markup = '';
    if (user.text !== undefined) {
        if (user.id == user.text) {
            return '<div class="manual">' + user.text + '</div>';
        } else {
            return '<div class="header"><h5>' + user.text + '</h5></div>';
        }
    }
    markup = '<div class="result">';
    if (user.id !== undefined) {
        markup += '<span class="username"><p>' + user.id + '</p></span>';
    }
    if(user.name !== undefined || user.email !== undefined) {
        markup += '<span class="info">';
        if (user.name !== undefined) {
            markup += '<p>' + user.name + '</p>';
        }
        if (user.email !== undefined) {
            markup += '<p>&lt;' + user.email + '&gt;</p>';
        }
        markup += '</span>';
    }
    markup += '</div>';
    return markup;
}
function userFormatSelection(user) {
    return user.id;
}
'''), type="text/javascript"))

            stream = stream | Transformer('//head').append(tag.script('''
jQuery(document).ready(
    function($) {
        %s
});
''' % js, type="text/javascript"))

        return stream
示例#53
0
    def filter_stream(self, req, method, filename, stream, data):

        if filename == 'ticket.html':

            # setup variables
            javascript = [self.javascript()]

            onload = []
            onsubmit = []
            policy_dict = self.policy_dict()

            # add JS functions to the head block
            for policy in self.policies:
                policy_javascript = policy.javascript()
                
                if policy_javascript:
                    add_script(req, policy_javascript)
#                    javascript.append(policy_javascript)

            policies = self.parse()
            
            for name, policy in policies.items():

                # insert the condition into the JS
                conditions = policy['condition']
                _conditions = []
                for condition in conditions:
                    _condition = {}
                    _condition['field'] = condition['field']
                    _condition['comparitor'] = camelCase(condition['comparitor'])
                    comp_type =  self.comparitors[condition['comparitor']]
                    value = condition['value']
                    if comp_type == 'Array':
                        _condition['value'] = '[ %s ]' % ', '.join(["'%s'" % v for v in value])
                    else:
                        _condition['value'] = "'%s'" % value
                    _conditions.append("{field: '%(field)s', comparitor: %(comparitor)s, value: %(value)s}" % _condition)
                condition = '%s = [ %s ];' % (name, ', '.join(_conditions))
                javascript.append(condition)

                # find the correct handler for the policy
                for action in policy['actions']:
                    handler =  policy_dict.get(action['name'])
                    if handler is None:
                        self.log.error('No ITicketSubmitPolicy found for "%s"' % action['name'])
                        continue
                
                    # filter the stream
                    stream = handler.filter_stream(stream, name, policy['condition'], *action['args'])


                    # add other necessary JS to the page
                    policy_onload = handler.onload(name, policy['condition'], *action['args'])
                    if policy_onload:
                        onload.append(policy_onload)
                    policy_onsubmit = handler.onsubmit(name, policy['condition'], *action['args'])
                    if policy_onsubmit:
                        onsubmit.append(policy_onsubmit)

            # insert onload, onsubmit hooks if supplied
            if onload:
                javascript.append(self.onload(onload))

            if onsubmit:
                javascript.append(self.onsubmit(onsubmit))
                stream |= Transformer("//form[@id='propertyform']").attr('onsubmit', 'validate()')

            # insert head javascript
            if javascript:
                javascript = '\n%s\n' % '\n'.join(javascript)
                javascript = tag.script(Markup(javascript), **{ "type": "text/javascript"})
                
                stream |= Transformer("head").append(javascript)

        return stream
示例#54
0
    def filter_stream(self, req, method, filename, stream, data):
        if filename == "ticket.html":
            ##Check Permissions
            enchants = self.config.get('blackmagic', 'tweaks', '')
            for field in (x.strip() for x in enchants.split(',')):
                self.env.log.debug("Checking %s:" % field)
                disabled = False
                hidden = False
                #Get a list of the permissions from the config, split them on commas and remove spaces
                perms = self.config.get('blackmagic', '%s.permission' % field, '').upper()
                #Default to not having permissions
                hasPerm = True
                if perms:
                    hasPerm = False
                    #If there are permissions
                    self.env.log.debug("perm: %s" % len(perms))
                    perms = perms.split(',')
                    #walk the list we got back and check the request for the permission
                    for perm in perms:
                        perm = perm.strip()
                        self.env.log.debug("Checking perm: %s" % perm)
                        if perm in req.perm:
                            self.env.log.debug("User has perm: %s" % perm)
                            hasPerm = True
                    if hasPerm == False:
                        denial = self.config.get('blackmagic', '%s.ondenial' % field, None)
                        if denial:
                            if denial == "disable":
                                disabled = True
                            elif denial == "hide":
                                hidden = True
                            else:
                                disabled = True
                        else:
                            disabled = True

                self.env.log.debug('hasPerm: %s' % hasPerm)
                if hidden == False:
                    if self.config.get('blackmagic', '%s.label' % field, None):
                        labelTXT = self.config.get('blackmagic', '%s.label' % field)
                        label = tag.label("%s:" %labelTXT, for_="field-%s" % field)
                        stream = stream | Transformer('//label[@for="field-%s"]' % field).replace(label)

                if hasPerm == False:   
                    if istrue(self.config.get('blackmagic', '%s.hide' % field, None)):
                        hidden = True
                        
                    if disabled or istrue(self.config.get('blackmagic', '%s.disable' % field, False)):
                        stream = stream | Transformer('//*[@id="field-%s"]' % field).attr("disabled", "disabled")
                        label = self.config.get('blackmagic', '%s.label' % field)
                        if not label:
                            label = field.capitalize()
                        if not self.gray_disabled:
                            stream = stream | Transformer('//label[@for="field-%s"]' % field).replace(
                                tag.strike()('%s:' % label)
                            )
                        else:
                            stream = stream | Transformer('//label[@for="field-%s"]' % field).replace(
                                tag.span(style="color:%s" % self.gray_disabled)('%s:' % label)
                            )
                    
                    if hidden or istrue(self.config.get('blackmagic', '%s.hide' % field, None)):
                        stream = stream | Transformer('//th[@id="h_%s"]' % field).replace(" ") 
                        stream = stream | Transformer('//td[@headers="h_%s"]' % field).replace(" ")
                        stream = stream | Transformer('//label[@for="field-%s"]' % field).replace(" ")
                        stream = stream | Transformer('//*[@id="field-%s"]' % field).replace(" ")

                    
                if hidden == False:
                    if self.config.get('blackmagic', '%s.notice' % field, None):
                        stream = stream | Transformer('//*[@id="field-%s"]' % field).after(
                            tag.br() + tag.small(class_="notice-%s" %field)(
                                tag.em()(
                                    Markup(self.config.get('blackmagic', '%s.notice' % field))
                                )
                            )
                        )
                    
                tip = self.config.get('blackmagic', '%s.tip' % field, None)
                if tip:
                    stream = stream | Transformer('//div[@id="banner"]').before(
                        tag.script(type="text/javascript", 
                        src=req.href.chrome("blackmagic", "js", "wz_tooltip.js"))()
                    )
                    
                    stream = stream | Transformer('//*[@id="field-%s"]' % field).attr(
                        "onmouseover", "Tip('%s')" % tip.replace(r"'", r"\'")
                    )
                        
                    
        return stream
示例#55
0
 def script_tag(path=None, content=None):
     kw = { 'type' : "text/javascript"}
     if path:
         kw['src'] = link_builder(map_script(path, debug))
     return tag.script(content , **kw)
示例#56
0
    def expand_macro(self, formatter, name, content, args=None):
        # Utility methods
        def lte_ie8(req):
            user_agent = formatter.req.get_header('user-agent')
            msie = user_agent.find('MSIE ')
            return (msie != -1) and user_agent[msie + 5:msie + 6] in ['6', '7', '8']

        def after_AS(string):
            index = string.find(' AS ')
            return index > 0 and string[index + 4:] or string

        def before_AS(string):
            index = string.find(' AS ')
            return index > 0 and string[:index] or string
        # add scripts
        if lte_ie8(formatter.req):
            add_script(formatter.req, "statushistorychart/js/flot/excanvas.js")
        add_script(formatter.req, "statushistorychart/js/flot/jquery.flot.js")
        add_script(formatter.req, "statushistorychart/js/flot/jquery.flot.time.js")
        add_script(formatter.req, "statushistorychart/js/enabler.js")
        # from macro parameters
        query = None
        query_href = None
        status_list = ['new', 'assigned', 'accepted', 'closed']  # default
        if(content):
            # replace parameters
            for match in reversed([match for match in re_param.finditer(content)]):
                param_name = match.group(0)
                if param_name == '$USER':
                    authname = formatter.req.authname
                    if authname == 'anonymous':
                        authname = 'anonymous||somebody'
                    content = content.replace(param_name, authname)
                else:
                    param_value = formatter.req.args.get(param_name[1:])
                    if param_value:
                        content = content.replace(param_name, param_value)
            # execute query
            query = Query.from_string(formatter.env, content)
        field = query and query.id or 'status'  # stopgap implementation; I use 'report' for y-axis parameter
        field = filter(lambda x: x['name'] == field, TicketSystem(self.env).fields)
        if len(field) <= 0:
            return tag.div(tag.strong('Error: Macro %s failed' % name),
                       tag.pre("%s is not field name" % query.id), class_="system-message")
        field = field[0]
        custom = 'custom' in field and field['custom'] or None
        status_list = query and query.format and query.format.split('/') or \
                      'options' in field and copy.copy(field['options']) or status_list
        if field['name'] == 'status' and not (query and query.format):
            def isprime(item):
                primaries = ['new', 'assigned', 'accepted', 'closed']
                return (item in primaries and [primaries.index(item)] or [len(primaries)])[0]
            status_list.sort(key=isprime)
        if '*' not in status_list:
            status_list.append('*')
        default_status = status_list.index('*')
        # execute query for ids of ticket
        if(query and len(query.constraint_cols) > 0):
            result = query.execute() or [{'id':-1}]  # Sentinel for no result
            cond = "ticket.id in (%s)" % ', '.join([str(t['id']) for t in result])
        elif formatter.resource.realm == 'milestone':
            cond = "ticket.milestone='%s'" % formatter.resource.id
        elif('query_tickets' in formatter.req.session):  # You Feeling Lucky
            query_tickets = formatter.req.session.get('query_tickets', '')
            query_href = formatter.req.session.get('query_href', '')
            tickets = len(query_tickets) and query_tickets.split(' ') or ['-1']  # Sentinel for no result
            cond = "ticket.id in (%s)" % ', '.join(tickets)
        else:
            raise TracError("%sMacro: Empty. There are no content and no context." % name)
        # execute query for value changes of each ticket
        join_clause_dummy = ''
        join_clause = "JOIN ticket_custom ON ticket.id = ticket_custom.ticket and ticket_custom.name = '%s'"
        cursor = formatter.env.get_read_db().cursor()
        cursor.execute("""
                SELECT id, time, null, %s
                    FROM ticket
                    %s
                    WHERE %s
                UNION
                SELECT id, ticket_change.time, oldvalue, newvalue
                    FROM ticket
                    JOIN ticket_change ON ticket.id = ticket_change.ticket
                    WHERE %s AND field='%s'
                ORDER BY id, time
                """ % (custom and "'\uFEFF'" or field['name'],  # ZERO WIDTH NO-BREAK SPACE; uses for mark of invalid data
                       custom and (join_clause % field['name']) or join_clause_dummy,
                       cond, cond, field['name']))
        changes = [row for row in cursor.fetchall()]
        # transform (ticket, time, status)* ==> (ticket <>- status)*
        tid = 0  # position of ticket id
        tickets = {}
        for change in changes:
            ticket = tickets.get(change[tid])  # slot is exist, or
            if ticket is None:
                ticket = tickets[change[tid]] = []  # create new slot and use it
            ticket.append(list(change))
        # generate status_list splitted, {a, b+c, d} => {a:0, b+c:1, b:1, c:1, d:2}
        status_list_splitted = {}
        for index, status in enumerate(map(before_AS, status_list)):
            status_list_splitted[status] = index
            if status.find('+') >= 0:
                for each in status.split('+'):
                    status_list_splitted[each] = index
#        groupstats = self.compmgr[DefaultTicketGroupStatsProvider]
#        ticket_groups = groupstats._get_ticket_groups()
#        for group in ticket_groups:
#            pass
        for tid in tickets:
            if len(tickets[tid]) > 1:
                tickets[tid][0][3] = tickets[tid][1][2]  # override last value with initial value
        # generate data
        data = []
        # points
        too_many_tickets = len(tickets) > 200
        for no, tid in enumerate(sorted(tickets)):
            if not too_many_tickets or tickets[tid][-1][3] != 'closed':
                void, time, void, state = tickets[tid][-1]  # @UnusedVariable
                index = status_list_splitted.get(state, default_status)
                data.append({'points': {'show': True, 'radius': 8, 'color': no},
                             'label': tid,
                             'data': [[time / 1000, index]]})
        # lines
        for no, tid in enumerate(sorted(tickets)):
            data.append({'color': no, 'label': tid,
                         'data': [[time / 1000, status_list_splitted.get(state, default_status)]
                                  for void, time, void, state in tickets[tid]]})  # @UnusedVariable
        from trac import __version__ as VERSION
        if VERSION[0:1] != '0':
        # render for trac 1.0 or later
            add_script_data(formatter.req, {'statushistorychart_yaxis': map(after_AS, status_list)})
            add_script_data(formatter.req, {'statushistorychart_data': data})
            return tag.a(_("Return to Last Query"), href=query_href) \
                 + tag.div(id="statushistorychart", style="width: 800px; height: 400px;")
        else:  # if trac < 1.0 or earlier
            from trac.util.presentation import to_json
            return tag.script("var statushistorychart_yaxis = %s; var statushistorychart_data = %s" \
                              % (to_json(map(after_AS, status_list)), to_json(data)),
                              type="text/javascript") \
                 + tag.a(_("Return to Last Query"), href=query_href) \
                 + tag.div(id="statushistorychart", style="width: 800px; height: 400px;")