Angular Marked and Inappbrowser 在系统浏览器中打开所有链接

Angular Marked and Inappbrowser opening all links in the system browser

我正在开发一个 Ionic 应用程序,用户可以在其中 post 降价内容。为了完成这项工作,我使用了 angular-marked 库。在应用程序中,我希望在 OS 的默认浏览器中打开所有降价链接,所以我做了两件事。

  1. 我写了一个 angular 指令,它使用 cordova-plugin-inappbrowser 的 ngCordova 包装器强制链接在 OS' 浏览器中打开。

  2. 我已将 angular-marked 的配置设置为使用此指令呈现所有链接。

问题是链接无法在系统浏览器中打开。它们在当前 WebView 中打开。可能是我的指令不好,或者在这种情况下指令甚至不适合使用。

我在写代码做什么?如何解决我在系统浏览器中打开链接的问题?

我的指令。

  .directive('fab-extLink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){

            return {
                restrict: 'A',
                link: function(scope, elem, attrs) {
                    elem.bind('click', function(e) {
                        // Stop the link from opening.
                        e.preventDefault();

                        // Open the link with the operating system browser.
                        $cordovaInAppBrowser.open(attrs.href, '_system');
                    });
                }
            };
    }])

我的配置

.config( [
      '$compileProvider',
      'markedProvider',
      function( $compileProvider, markedProvider)
      {
        $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);

        // When markdown is rendered use the external link directive.
        markedProvider.setRenderer({
          link: function(href, title, text) {
            return '<a fab-extLink href="' + href + '"' + (title ? ' title="' + title + '"' : '') + '>' + text + '</a>';
          }
        });
      }
    ])

你的代码有两个问题

1。 angular 指令的名称应该在 camelCase 中,它将在 HTML 中转换为 kebab-case。这很容易修复,只需更改

 .directive('fab-extLink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){

 .directive('fabExtlink', ['$cordovaInAppBrowser', function($cordovaInAppBrowser){

2。在你的情况下,你的 HTML 中有 <a fab-extlink>,但 angular 没有 $compile(实例化)它。

这是一个困难的问题(如果你不想猴子补丁 angular-marked)。

angular-marked 使用 element.html(marked(text, scope.opts || null)); 设置元素的内部 HTML,它跳过了 angular 的编译过程,所以指令没有被初始化..

一种解决方法是使用全局函数(我知道这并不优雅):

在app.run中定义:

.run(function ($cordovaInAppBrowser) {
  window.openInSystemBrowser=function(link){
     $cordovaInAppBrowser.open(link, '_system');
  };

和配置 angular-标记为使用 onclick,这样它就可以独立于 angular。

markedProvider.setRenderer({
        link: function (href, title, text) {
          return '<a onclick="openInSystemBrowser(\'' + href + '\')"' + (title ? ' title="' + title + '"' : '') + '>' + text + '</a>';
        }
      });

我能想到的另一种方法是分叉和修补 angular-marked.


猴子补丁解决方案:

  1. 打开angular-marked.js
  2. 替换

    element.html(marked(text, scope.opts || null));
    

    element.replaceWith($compile(marked(text, scope.opts || null))(scope));
    

更新2

我检查了 repo,最新版本的 angular-marked (v1.2) 支持名为 compile 的属性,正是为了做到这一点。

例如

<marked compile="true">
          # Markdown [Google](http://www.google.com)
          *It works!*
</marked>

所以,总而言之..


TLDR 版本

1。变化

 .directive('fab-extLink', ...

 .directive('fabExtlink', ...

2。将属性 compile='true' 添加到 <marked> 指令

如果您正在寻找一种简单的方法来在带有标记的移动设备上的本机浏览器中打开链接,您可以尝试在 angular.config 中进行设置:

markedProvider.setRenderer({
  link: function(href, title, text) {
    return "<a href='" + href + "'" + (title ? " title='" + title + "'" : '') + " onclick='window.open("+href+", '_system')'" + " target='_system'>" + text + "</a>";
  }
});

然后你需要像这样绑定一个 onDeviceReady 函数:

document.addEventListener('deviceready', onDeviceReady, false);

function onDeviceReady() {
  window.open = cordova.InAppBrowser.open;
}