Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: headless/lib/renderer/headless_content_renderer_client.cc

Issue 2049363003: Adds support for headless chrome embedder mojo services (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix a bug with mojo bindings after the onload event fired. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "headless/lib/renderer/headless_content_renderer_client.h" 5 #include "headless/lib/renderer/headless_content_renderer_client.h"
6 6
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/public/renderer/render_frame.h"
9
7 namespace headless { 10 namespace headless {
8 11
9 HeadlessContentRendererClient::HeadlessContentRendererClient() {} 12 HeadlessContentRendererClient::HeadlessContentRendererClient() {}
10 13
11 HeadlessContentRendererClient::~HeadlessContentRendererClient() {} 14 HeadlessContentRendererClient::~HeadlessContentRendererClient() {}
12 15
16 void HeadlessContentRendererClient::RunScriptsAtDocumentStart(
17 content::RenderFrame* render_frame) {
18 render_frame->ExecuteJavaScript(base::UTF8ToUTF16(R"(
19 // Shim to let code use define() instead of mojo.define()
20 window.define = (function() {
21 let moduleCache = new Map();
22 return function(name, deps, factory) {
23 let promise = moduleCache.get(name);
24 if (promise === undefined) {
25 // This promise must be cached as mojo.define will only call the
26 // factory function the first time the module is defined.
27 promise = new Promise(resolve => {
28 mojo.define(name, deps, (...modules) => {
29 let result = factory(...modules);
30 resolve(result);
31 return result;
32 });
33 });
34 moduleCache.set(name, promise);
35 }
36 return promise;
37 }
38 })();
39
40 // This code is run before the browser has sent us the mojo bindings so
41 // we need to get fancy and use nested proxy classes to define a promise
42 // to an arbitary window.mojo.services.myModule.myInterface.
43 if (window.hasOwnProperty("mojo")) {
44 let mojoBindings = new Map();
45 let resolvePending = true;
46 window.mojo.services = new Proxy({}, {
47 get: function(target, serviceName) {
48 if (!(serviceName in target)) {
49 var interfaceProxy = new Proxy({}, {
50 get: function(target, interfaceName) {
51 let name = serviceName + "::" + interfaceName;
52 let binding = mojoBindings.get(name);
53 if (binding === undefined) {
54 binding = {};
55 binding.promise = new Promise(function(resolve, reject) {
56 binding.resolve = resolve;
57 binding.reject = reject;
58 if (!resolvePending)
59 reject();
60 });
61 mojoBindings.set(name, binding);
62 }
63 return binding.promise;
64 },
65 set: function(target, name, value) {
66 return false;
67 }
68 });
69 target[serviceName] = interfaceProxy;
70 return interfaceProxy;
71 }
72 return target[serviceName];
73 },
74 set: function(target, name, value) {
75 return false;
76 }
77 });
78
79 // Resolve promises for the listed |serviceNames|.
80 window.mojo.resolvePromisesForService = function(serviceNames) {
Eric Seckler 2016/06/14 17:50:48 I'd suggest to rename this function to ..ForServic
alex clarke (OOO till 29th) 2016/06/14 19:05:08 Makes sense, done.
81 let numServices = serviceNames.length;
82 for (let i = 0; i < numServices; ++i) {
83 let serviceName = serviceNames[i];
84 // Use mojo to obtain the module binding.
85 define([
86 serviceName,
87 "mojo/public/js/core",
88 "mojo/public/js/router",
89 "content/public/renderer/frame_service_registry",
90 ], function(serviceMojom, mojoCore, routerModule,
91 serviceProvider) {
92 // A mojom binding may contain bindings for a number of intefaces.
Eric Seckler 2016/06/14 17:50:48 typo (interfaces)
alex clarke (OOO till 29th) 2016/06/14 19:05:08 Done. Note to self install the spell checker on m
93 // Iterate through all of them and resolve any promises.
94 for (var m in serviceMojom) {
95 if (typeof serviceMojom[m] == "object") {
96 let service = serviceMojom[m];
97 let binding = mojoBindings.get(service.name);
98 let interface = new service.proxyClass(
99 new routerModule.Router(
100 serviceProvider.connectToService(service.name)));
101 if (binding === undefined) {
102 // Store resolved promise in case binding is requested.
103 mojoBindings.set(
104 service.name, {"promise": Promise.resolve(interface)});
105 } else {
106 binding.resolve(interface);
107 mojoBindings.delete(service.name);
Eric Seckler 2016/06/14 17:50:48 I might be missing something, but if you delete th
alex clarke (OOO till 29th) 2016/06/14 19:05:08 Mmm yes this is a bad idea. What I really want to
108 }
109 }
110 }
111 });
112 }
113 // Reject any remaining promises.
114 for (let [key, value] of mojoBindings) {
115 if ("reject" in value) {
116 value.reject();
117 }
118 }
119 // Reject any subsequent unknown properties.
120 resolvePending = false;
121 };
122 } )"));
123 }
124
13 } // namespace headless 125 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698