扩展< object>在飞镖 [英] Extending <object> in Dart

查看:84
本文介绍了扩展< object>在飞镖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Dart < object> 元素不支持访问者访问< object> .contentDocument 并且因此我想扩大对象来添加功能。



我看了一下 ObjectElement 的实现,我基本上需要添加这些行:

  @DomName('HTMLObjectElement.contentDocument')
@DocsEditable()
Document get contentDocument => _blink.BlinkHTMLObjectElement.instance.contentDocument_Getter_(本);

但是,我不知道如何做到这一点。我目前使用的解决方案是使用代理将所有调用重定向到底层的 JsObject ,但说实话,这不仅是肮脏的,也不可能维护。 / p>

/ *更新以解释所有邪恶的根源* /



我正在开发的项目中,我想在网站上显示用户上传的SVG,并让用户通过插入其他SvgElements或删除其他SVG来操作这些SVG。

当将SVG作为字符串下载并通过显示它们时,

container.append(new SvgElement(svgCode))



我遇到了一些非常奇怪的显示错误,例如SVG中嵌入的图像被替换,甚至被删除以及带有掩码的其他错误。 使用< object> 标记解决了该问题,并将其数据属性设置为SVG的url 。 SVG呈现正确。话虽如此,另一个问题出现了。我无法访问和操作SVG DOM,因为它位于< object> 标记内,并且无法使用 contentDocument访问标记的文档



考虑到这一切后,几乎只剩下两个选项:


  1. 我使用< object> 标签,但没有显示错误,但无法操作SVG或

  2. 我从SVG的源代码创建新的SvgElements,并将它们附加到DOM,让我操纵SVG,但有显示错误。


    由于显示错误并不是一个真正的解决方案,我只能使用第一个选项,使用< object> 标签并使用Javascript来解决访问对象的contentDocument。



    正如您所见,访问 contentDocument 并不总是一个安全问题,也不允许使用它,只是一个快速而脏的解决问题。

    使用JsObject访问 contentDocument 时, JsObject返回而不是元素。因此,我不仅需要在任何地方更新我的代码,而且它也变得非常难看,因为我必须使用带有 callMethod(blabla)的JsObject。

    解决方案



      class MyObjectElement扩展ObjectElement {
    static bool _isRegistered = false;

    static register(){
    if(!_isRegistered){
    document.registerElement('my-object',MyObjectElement,
    extendsTag:'object');
    _isRegistered = true;



    factory MyObjectElement(){
    var result = document.createElement('object','my-object');
    返回结果;
    }

    MyObjectElement.created():super.created();

    js.JsObject get contentDocument {
    //似乎不适用于自定义元素。
    返回新的js.JsObject.fromBrowserObject(this)['contentDocument'];


    $ / code>

    使用它就像



    MyObjectElement.register();
    var obj = new MyObjectElement()
    ..data =
    https://www.suntico.com/wp-content/uploads/DemoStampRotate01-e1400242575670.png ;
    document.body.append(obj);

    The Dart <object> element does not support a getter to access <object>.contentDocument and thus I thought about extending the object to add the functionality.

    I took a look at the implementation of the ObjectElement and I basically need to add these lines:

     @DomName('HTMLObjectElement.contentDocument')
     @DocsEditable()
     Document get contentDocument => _blink.BlinkHTMLObjectElement.instance.contentDocument_Getter_(this);
    

    However, I have no idea how to do this. The solution I am using at this time is with a proxy which redirects all calls to the underlying JsObject but to be honest, this is not just dirty, it impossible to maintain.

    /* Updated to explain the root of all evil */

    When starting the project I am working on, I wanted to display SVGs, which are uploaded by the user, on the website and let the user manipulate these SVGs by inserting additional SvgElements or removing others.

    When downloading the SVGs as a String and displaying them by

    container.append(new SvgElement(svgCode))

    I got really strange display bugs such that embeded images in the SVGs are displaced or even removed and other bugs with masks.

    The problem was solved by using an <object> tag and set setting its data attribute to the SVG's url. The SVGs are rendered correctly. That being said, another issue came up. I wasn't able to access and manipulate the SVGs DOM because it's inside an <object> tag and the tag's document cannot be accessed by using contentDocument.

    When taking all this into account, there are pretty much only two options left:

    1. I use the <object> tag with no display bugs but not being able to manipulate the SVGs or
    2. I create new SvgElements fromt the SVG's source and append them to the DOM which let's me manipulate the SVGs but having display bugs.

    Since having display bugs isn't really a solution I can only make use of the first option, using an <object> tag and working around with Javascript to access the object's contentDocument.

    As you can see, accessing the contentDocument is not always a security issue and not allowing to make use of it, is just a quick and dirty solution of a problem.

    When accessing the contentDocument by using a JsObject, I get a JsObject back and not an Element. Thus I do not only have to update my code pretty much everywhere, but it gets also pretty ugly since I have to use the JsObject with callMethod(blabla).

    解决方案

    class MyObjectElement extends ObjectElement {
      static bool _isRegistered = false;
    
      static register() {
        if (!_isRegistered) {
          document.registerElement('my-object', MyObjectElement,
              extendsTag: 'object');
          _isRegistered = true;
        }
      }
    
      factory MyObjectElement() {
        var result = document.createElement('object', 'my-object');
        return result;
      }
    
      MyObjectElement.created() : super.created();
    
      js.JsObject get contentDocument {
        // doesn't seem to work with a custom element.
        return new js.JsObject.fromBrowserObject(this)['contentDocument'];
      }
    }
    

    use it like

    MyObjectElement.register(); var obj = new MyObjectElement() ..data = "https://www.suntico.com/wp-content/uploads/DemoStampRotate01-e1400242575670.png"; document.body.append(obj);

    这篇关于扩展&lt; object&gt;在飞镖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆