def _inject_extra_elements(self, tree: html.Element, xurl: str):
        if xurl == None: return

        if len(tree) == 0 or tree[0].tag != "head":
            return

        base = tree.findall("base")
        if len(base) > 0: return

        base = html.Element("base")
        base.attrib["ref"] = xurl
        tree.insert(0, base)
Esempio n. 2
0
    def render_template(self, template, values=None, engine='ir.qweb'):
        res = super(IrUiView, self).render_template(template, values, engine)
        res_copy = res

        try:
            website = request.website
        except:
            website = False

        optimiser = website and self.env['optimiser.optimiser'].sudo().search(
            [('website_id', '=', website.id)])

        try:
            res = res.decode("utf-8", "ignore").encode("ascii",
                                                       "xmlcharrefreplace")
        except:
            pass

        if values and values.get('request', False) and optimiser:
            res = fromstring(res)
            head = res.find('.//head')
            body = res.find('.//body')
            no_head_body = False

            if not body or not head:
                no_head_body = True

            if not no_head_body:
                if not request.httprequest.is_xhr:

                    if optimiser.load_css_async or optimiser.css_bottom:
                        styles = res.cssselect('link[rel="stylesheet"]')
                        ie_styles = ""

                        for style in styles:
                            ie_styles += htmlstring(
                                style, method="html").decode("utf-8").strip(
                                ).strip("\n").rstrip('>') + "/>"

                            if optimiser.css_bottom:
                                body.insert(len(body), style)

                            if optimiser.load_css_async:
                                noscript_tag = Element('noscript')
                                tmp_style = copy.copy(style)
                                noscript_tag.insert(0, tmp_style)

                                parent = style.getparent()
                                parent.insert(
                                    parent.index(style) + 1, noscript_tag)

                                style.attrib['rel'] = 'preload'
                                style.attrib['as'] = 'style'
                                style.attrib[
                                    'onload'] = "this.onload=null;this.rel='stylesheet'"

                        script_tag_for_converting_styles = Element("script")
                        script_tag_for_converting_styles.attrib[
                            'data-not-touchable'] = 'true'
                        script_tag_for_converting_styles.text = "function supportsToken(token){return function(relList){if(relList && relList.supports && token){return relList.supports(token)} return false}}; window.onload = function(){if(!supportsToken('preload')(document.createElement('link').relList)){var links=document.querySelectorAll('link[as=\"style\"][rel=\"preload\"]'); if(links.length){for(var i in links){links[i].rel='stylesheet'}}}}"
                        body.insert(len(body),
                                    script_tag_for_converting_styles)

                        script_tag_for_checking_ie = Element('script')
                        script_tag_for_checking_ie.attrib[
                            'data-not-touchable'] = 'true'
                        script_tag_for_checking_ie.text = "function isIE(){var myNav=navigator.userAgent.toLowerCase(); return (myNav.indexOf('msie') != -1 || myNav.indexOf('trident') != -1) ? true : false;}; if(isIE()){var div=document.createElement('div');div.innerHTML='%s';document.head.appendChild(div);}" % ie_styles
                        head.insert(len(head), script_tag_for_checking_ie)

                    if optimiser.js_bottom:
                        scripts = res.cssselect(
                            'script:not([data-not-touchable])')

                        for script in scripts:
                            body.insert(len(body), script)

                    if optimiser.load_js_async:
                        scripts = res.cssselect('script[src]')
                        lazy_scripts = res.cssselect('script[data-src]')
                        optimiser_js_async_setting = optimiser.load_js_async

                        if "shop/payment" in request.httprequest.path:
                            optimiser_js_async_setting = 'async'

                        for script in scripts:
                            if optimiser_js_async_setting == 'async':
                                script.attrib['defer'] = 'defer'
                            else:
                                script.attrib[
                                    'data-optimiser-src'] = script.attrib[
                                        'src']
                                script.attrib.pop("src", None)

                        for script in lazy_scripts:
                            if optimiser_js_async_setting == 'async':
                                script.attrib['defer'] = 'defer'
                                script.attrib['src'] = script.attrib[
                                    'data-src']
                            else:
                                script.attrib[
                                    'data-optimiser-src'] = script.attrib[
                                        'data-src']

                            script.attrib.pop("data-src", None)

                        if optimiser_js_async_setting == 'sync_lazy':
                            load_lazy_scripts = Element("script")
                            load_lazy_scripts.text = """function loadScripts() {
							    var scripts = Array.from(document.querySelectorAll("script[data-optimiser-src]"));
								sessionStorage.setItem('secondTimeLoad', '1');
							    function loadScript(scripts) {
							        if(scripts.length){
							            var attr = scripts[0].getAttribute("data-optimiser-src");
							            scripts[0].setAttribute("src", attr);
							            scripts[0].removeAttribute("data-optimiser-src");
							            scripts[0].onload = function () {
							                scripts.shift();
							                loadScript(scripts);
							            }
							        }
							    }

							    loadScript(scripts)
							}

							window.addEventListener("scroll", function scrollEventFunction() {
								setTimeout(function(){loadScripts()},500)
							},{once: true})

							window.addEventListener("load", function () {
								var timer = sessionStorage.getItem('secondTimeLoad') ? 0 : 1500;
							    setTimeout(function () {
							        loadScripts()
							    }, timer);
							})"""
                            body.insert(len(body), load_lazy_scripts)

                    if optimiser.page_loading:
                        page_loader_script_tag = Element("script")
                        page_loader_script_tag.text = "window.addEventListener('" + optimiser.show_page_loading_until + \
                                                      "', function(){document.querySelector('div.optimiser-page-loader').remove();});"
                        page_loader_image_width = optimiser.page_loading_image_width if optimiser.page_loading_image_width else "100px"
                        page_loader_image_height = optimiser.page_loading_image_height if optimiser.page_loading_image_height else "100px"
                        page_loader_image_position_top = optimiser.page_loading_image_pos_top if optimiser.page_loading_image_pos_top else "50%"
                        page_loader_image_position_left = optimiser.page_loading_image_pos_left if optimiser.page_loading_image_pos_left else "50%"
                        page_loader_bg = optimiser.page_loading_bg_color if optimiser.page_loading_bg_color else "#FFFFFF"
                        page_loader_bg_transparency = optimiser.page_loading_bg_transparency if optimiser.page_loading_bg_transparency else 1
                        page_loader_bg_image = (optimiser.show_default_page_loading_image or optimiser.page_loading_image) \
                                               and "background-image: url(/optimiser-page-loader-image);" or ""

                        page_loader_div = Element(
                            "div", **{
                                'class':
                                "optimiser-page-loader",
                                'style':
                                "position: fixed;"
                                "left: 0;"
                                "top: 0;"
                                "width: 100%%;"
                                "height: 100%%;"
                                "z-index: 9999999999;"
                                "%s"
                                "background-repeat: no-repeat;"
                                "background-size: %s %s;"
                                "background-color: rgba%s;"
                                "background-position: %s %s;"
                                "background-attachment: fixed;" %
                                (str(page_loader_bg_image),
                                 str(page_loader_image_width),
                                 str(page_loader_image_height),
                                 str(
                                     hex2rgb(page_loader_bg,
                                             page_loader_bg_transparency)),
                                 str(page_loader_image_position_top),
                                 str(page_loader_image_position_left))
                            })

                        body.insert(len(body), page_loader_script_tag)
                        body.insert(0, page_loader_div)

                    if len(optimiser.custom_content_ids) > 0:

                        contents = optimiser.custom_content_ids

                        for content in contents:
                            if content.content:
                                try:
                                    tmp = fromstring(content.content)
                                except:
                                    continue

                                if content.position.startswith('head'):
                                    html = head
                                else:
                                    html = body

                                position = len(
                                    html) if content.position.endswith(
                                        "end") else 0
                                head_content = tmp.find('.//head')

                                if head_content:
                                    for tmp_content in head_content:
                                        html.insert(position, tmp_content)
                                        position += 1
                                else:
                                    html.insert(position, tmp)

                if optimiser.preload_fonts and len(
                        optimiser.preload_fonts_ids) > 0:
                    for font in optimiser.preload_fonts_ids:
                        preload_font_elem = Element('link')
                        preload_font_elem.attrib['rel'] = "preload"
                        preload_font_elem.attrib['href'] = font.path
                        preload_font_elem.attrib['as'] = "font"
                        preload_font_elem.attrib['crossorigin'] = ""
                        head.insert(1, preload_font_elem)

                if optimiser.enable_lazy_load_front:
                    images = res.cssselect('img:not(.og_not_lazy)')
                    bg_images = res.cssselect(
                        '[style*="background-image"]:not(.optimiser-page-loader):not(.og_not_lazy)'
                    )
                    loading_image = ((optimiser.show_default_image_loading_image or optimiser.loading_image)
                                     and "/optimiser-loading") \
                                    or "/optimiser/static/src/img/empty.png"
                    check_class_regex = re.compile(
                        r"^.*\s*optimiser_lazy(\s+|$)")

                    if not request.httprequest.is_xhr:
                        lazy_loader_style = Element('style')
                        lazy_loader_style.text = 'img[src="/optimiser-loading"]{width:40px!important;height:40px!important;text-align:center;margin:auto;-o-object-fit:contain!important;object-fit:contain!important}'
                        head.insert(len(head), lazy_loader_style)

                    for bg_img in bg_images:
                        bg_style = bg_img.attrib['style']
                        find_bg_image = "background-image:"

                        try:
                            bg_image_index = bg_style.index(find_bg_image)
                        except:
                            continue

                        index_of_bg_image_start = bg_image_index + len(
                            find_bg_image)

                        try:
                            bg_style.index('url', index_of_bg_image_start)
                        except:
                            continue

                        try:
                            index_of_bg_image_end = bg_style.index(
                                ';', index_of_bg_image_start)
                        except:
                            try:
                                bg_style += ';'
                                index_of_bg_image_end = bg_style.index(
                                    ';', index_of_bg_image_start)
                            except:
                                continue

                        important_exists = ''

                        try:
                            important_exists = bg_style[
                                index_of_bg_image_start:
                                index_of_bg_image_end].index('!important')
                        except:
                            pass

                        start_of_string = bg_style[:bg_style.
                                                   index(find_bg_image)]
                        end_of_string = bg_style[index_of_bg_image_end + 1:]

                        if important_exists != '':
                            url_with_important_exist = bg_style[
                                index_of_bg_image_start:
                                index_of_bg_image_end].strip().rstrip(
                                    '!important').strip()
                            important_exists = '!important'
                            main_image_url = url_with_important_exist.strip(
                            ).lstrip('url(').rstrip(')').strip("'").strip('"')
                        else:
                            main_image_url = bg_style[
                                             bg_style.index('url', index_of_bg_image_start) + 3:index_of_bg_image_end] \
                             .strip().lstrip('(').rstrip(')').strip("'").strip('"')

                        bg_img.attrib[
                            'data-src'] = main_image_url if not 'data-src' in bg_img.attrib else bg_img.attrib[
                                'data-src']
                        bg_img.attrib['class'] = bg_img.attrib.get(
                            'class', '') if check_class_regex.match(
                                bg_img.attrib.get(
                                    'class', '')) else bg_img.attrib.get(
                                        'class', '') + ' optimiser_lazy'
                        bg_img.attrib['style'] = "background-image: url('" + \
                                                 loading_image + "')" + important_exists + ";" + \
                                                 start_of_string + \
                                                 end_of_string

                    for img in images:
                        img.attrib['data-src'] = img.attrib[
                            'src'] if not 'data-src' in img.attrib else img.attrib[
                                'data-src']
                        img.attrib['src'] = loading_image
                        img.attrib['class'] = img.attrib.get(
                            'class', '') if check_class_regex.match(
                                img.attrib.get(
                                    'class', '')) else img.attrib.get(
                                        'class', '') + ' optimiser_lazy'

                if optimiser.enable_recaptcha:
                    if optimiser.captcha_selectors:
                        selectors = res.cssselect(','.join(
                            optimiser.captcha_selectors.mapped('name')))

                        if selectors:
                            captcha_element_parent = Element('div')
                            captcha_element_parent.attrib[
                                'class'] = 'form-group field-recaptcha'

                            captcha_element = Element('div')
                            captcha_element.attrib['class'] = 'g-recaptcha'
                            captcha_element.attrib[
                                'data-sitekey'] = optimiser.captcha_site_key

                            captcha_element_parent.insert(0, captcha_element)

                            for element in selectors:
                                insert_element = None

                                for i in reversed(element.getchildren()):
                                    if i.tag == 'div':
                                        insert_element = i
                                        break

                                element.insert(element.index(insert_element),
                                               captcha_element_parent)

                            if not request.httprequest.is_xhr:
                                script_tag_for_recaptcha = Element("script")
                                script_tag_for_recaptcha.attrib[
                                    'src'] = 'https://www.google.com/recaptcha/api.js'
                                script_tag_for_recaptcha.attrib[
                                    'async'] = 'async'
                                script_tag_for_recaptcha.attrib[
                                    'defer'] = 'defer'
                                body.insert(len(body),
                                            script_tag_for_recaptcha)

                doctype = None if '/slides/embed' in request.httprequest.url else '<!DOCTYPE html>'

                res = htmlstring(res, method="html", doctype=doctype)
            else:
                res = res_copy

            if optimiser.compress_html:
                res = htmlmin.minify(res.decode("utf-8"),
                                     remove_empty_space=True,
                                     remove_comments=True)

            try:
                res = res.decode("utf-8")
            except:
                pass

        return res
Esempio n. 3
0
def cmd_wrap(root, tag, **kwargs):
    parent = Element(tag, **kwargs)
    parent.insert(0, root)
    return parent