Browse Source

LibWeb: Handle javascript: URLs inside LibWeb :^)

This patch makes it possible to execute JavaScript by clicking on an
anchor element with href="javascript:your_script_here()".
Andreas Kling 5 years ago
parent
commit
9b0bfcb8b7

+ 9 - 0
Libraries/LibWeb/DOM/Document.cpp

@@ -31,6 +31,7 @@
 #include <LibGUI/DisplayLink.h>
 #include <LibGUI/MessageBox.h>
 #include <LibJS/Interpreter.h>
+#include <LibJS/Parser.h>
 #include <LibJS/Runtime/Function.h>
 #include <LibJS/Runtime/GlobalObject.h>
 #include <LibWeb/Bindings/DocumentWrapper.h>
@@ -365,4 +366,12 @@ JS::Interpreter& Document::interpreter()
     return *m_interpreter;
 }
 
+JS::Value Document::run_javascript(const StringView& source)
+{
+    auto program = JS::Parser(JS::Lexer(source)).parse_program();
+    dbg() << "Document::run_javascript('" << source << "') will run:";
+    program->dump(0);
+    return document().interpreter().run(*program);
+}
+
 }

+ 2 - 0
Libraries/LibWeb/DOM/Document.h

@@ -121,6 +121,8 @@ public:
 
     JS::Interpreter& interpreter();
 
+    JS::Value run_javascript(const StringView&);
+
 private:
     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
 

+ 19 - 2
Libraries/LibWeb/HtmlView.cpp

@@ -32,6 +32,7 @@
 #include <LibGUI/ScrollBar.h>
 #include <LibGUI/Window.h>
 #include <LibGfx/PNGLoader.h>
+#include <LibJS/Runtime/Value.h>
 #include <LibWeb/DOM/Element.h>
 #include <LibWeb/DOM/ElementFactory.h>
 #include <LibWeb/DOM/HTMLAnchorElement.h>
@@ -232,8 +233,13 @@ void HtmlView::mousedown_event(GUI::MouseEvent& event)
             node->dispatch_event(MouseEvent::create("mousedown", offset.x(), offset.y()));
             if (RefPtr<HTMLAnchorElement> link = node->enclosing_link_element()) {
                 dbg() << "HtmlView: clicking on a link to " << link->href();
-                if (on_link_click)
-                    on_link_click(link->href());
+
+                if (link->href().starts_with("javascript:")) {
+                    run_javascript_url(link->href());
+                } else {
+                    if (on_link_click)
+                        on_link_click(link->href());
+                }
             } else {
                 if (event.button() == GUI::MouseButton::Left) {
                     layout_root()->selection().set({ result.layout_node, result.index_in_node }, {});
@@ -476,4 +482,15 @@ Gfx::Point HtmlView::compute_mouse_event_offset(const Gfx::Point& event_position
     };
 }
 
+void HtmlView::run_javascript_url(const String& url)
+{
+    ASSERT(url.starts_with("javascript:"));
+    if (!document())
+        return;
+
+    auto source = url.substring_view(11, url.length() - 11);
+    dbg() << "running js from url: _" << source << "_";
+    document()->run_javascript(source);
+}
+
 }

+ 1 - 0
Libraries/LibWeb/HtmlView.h

@@ -77,6 +77,7 @@ protected:
 private:
     virtual void did_scroll() override;
 
+    void run_javascript_url(const String& url);
     void layout_and_sync_size();
     void dump_selection(const char* event_name);
     Gfx::Point compute_mouse_event_offset(const Gfx::Point&, const LayoutNode&) const;