Skip to content

Commit 6f1ec71

Browse files
committed
expose capturePage API
1 parent e39e8b9 commit 6f1ec71

File tree

5 files changed

+92
-46
lines changed

5 files changed

+92
-46
lines changed

src/api/nw_current_window_internal.idl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ namespace nw.currentWindowInternal {
99
callback CapturePageCallback = void (DOMString dataUrl);
1010
[noinline_doc] dictionary CapturePageOptions {
1111
[nodoc] DOMString? format;
12+
[nodoc] DOMString? datatype;
1213
[nodoc] long? quality;
1314
};
1415
interface Functions {
1516
static void showDevTools();
16-
static void capturePage(optional CapturePageOptions options, optional CapturePageCallback callback);
17+
static void capturePageInternal(optional CapturePageOptions options, optional CapturePageCallback callback);
1718
};
1819
};

src/api/nw_window.idl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ namespace nw.Window {
44
void ([instanceOf=NWWindow] object createdWindow);
55
callback EventCallback = void();
66

7+
callback CapturePageCallback = void (DOMString dataUrl);
8+
[noinline_doc] dictionary CapturePageOptions {
9+
[nodoc] DOMString? format;
10+
[nodoc] DOMString? datatype;
11+
[nodoc] long? quality;
12+
};
713
[noinline_doc] dictionary CreateWindowOptions {
814
[nodoc] long? x;
915
[nodoc] long? y;
@@ -24,6 +30,7 @@ namespace nw.Window {
2430
[noinline_doc] dictionary NWWindow {
2531
// show devtools for the current window
2632
static void showDevTools();
33+
static void capturePage(optional CapturePageCallback callback, optional CapturePageOptions options);
2734
static void show();
2835
static void hide();
2936
static void focus();
@@ -60,5 +67,6 @@ namespace nw.Window {
6067
interface Events {
6168
[nocompile] static void onNewWinPolicy();
6269
[nocompile] static void onNavigation();
70+
[nocompile] static void LoadingStateChanged();
6371
};
6472
};

src/api/nw_window_api.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,19 @@ bool NwCurrentWindowInternalShowDevToolsFunction::RunAsync() {
3636
return true;
3737
}
3838

39-
NwCurrentWindowInternalCapturePageFunction::NwCurrentWindowInternalCapturePageFunction() {
39+
NwCurrentWindowInternalCapturePageInternalFunction::NwCurrentWindowInternalCapturePageInternalFunction() {
4040
}
4141

42-
NwCurrentWindowInternalCapturePageFunction::~NwCurrentWindowInternalCapturePageFunction() {
42+
NwCurrentWindowInternalCapturePageInternalFunction::~NwCurrentWindowInternalCapturePageInternalFunction() {
4343
}
4444

45-
bool NwCurrentWindowInternalCapturePageFunction::RunAsync() {
45+
bool NwCurrentWindowInternalCapturePageInternalFunction::RunAsync() {
4646
EXTENSION_FUNCTION_VALIDATE(args_);
4747

4848
scoped_ptr<ImageDetails> image_details;
49-
if (args_->GetSize() > 0) {
49+
if (args_->GetSize() > 1) {
5050
base::Value* spec = NULL;
51-
EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &spec) && spec);
51+
EXTENSION_FUNCTION_VALIDATE(args_->Get(1, &spec) && spec);
5252
image_details = ImageDetails::FromValue(*spec);
5353
}
5454

@@ -94,13 +94,13 @@ bool NwCurrentWindowInternalCapturePageFunction::RunAsync() {
9494
host->CopyFromBackingStore(
9595
gfx::Rect(view_size),
9696
bitmap_size,
97-
base::Bind(&NwCurrentWindowInternalCapturePageFunction::CopyFromBackingStoreComplete,
97+
base::Bind(&NwCurrentWindowInternalCapturePageInternalFunction::CopyFromBackingStoreComplete,
9898
this),
9999
kN32_SkColorType);
100100
return true;
101101
}
102102

103-
void NwCurrentWindowInternalCapturePageFunction::CopyFromBackingStoreComplete(
103+
void NwCurrentWindowInternalCapturePageInternalFunction::CopyFromBackingStoreComplete(
104104
const SkBitmap& bitmap,
105105
content::ReadbackResponse response) {
106106
if (response == content::READBACK_SUCCESS) {
@@ -110,7 +110,7 @@ void NwCurrentWindowInternalCapturePageFunction::CopyFromBackingStoreComplete(
110110
OnCaptureFailure(FAILURE_REASON_UNKNOWN);
111111
}
112112

113-
void NwCurrentWindowInternalCapturePageFunction::OnCaptureSuccess(const SkBitmap& bitmap) {
113+
void NwCurrentWindowInternalCapturePageInternalFunction::OnCaptureSuccess(const SkBitmap& bitmap) {
114114
std::vector<unsigned char> data;
115115
SkAutoLockPixels screen_capture_lock(bitmap);
116116
bool encoded = false;
@@ -154,7 +154,7 @@ void NwCurrentWindowInternalCapturePageFunction::OnCaptureSuccess(const SkBitmap
154154
SendResponse(true);
155155
}
156156

157-
void NwCurrentWindowInternalCapturePageFunction::OnCaptureFailure(FailureReason reason) {
157+
void NwCurrentWindowInternalCapturePageInternalFunction::OnCaptureFailure(FailureReason reason) {
158158
const char* reason_description = "internal error";
159159
switch (reason) {
160160
case FAILURE_REASON_UNKNOWN:

src/api/nw_window_api.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ class NwCurrentWindowInternalShowDevToolsFunction : public AsyncExtensionFunctio
2929
void Callback();
3030
};
3131

32-
class NwCurrentWindowInternalCapturePageFunction : public AsyncExtensionFunction {
32+
class NwCurrentWindowInternalCapturePageInternalFunction : public AsyncExtensionFunction {
3333
public:
34-
NwCurrentWindowInternalCapturePageFunction();
34+
NwCurrentWindowInternalCapturePageInternalFunction();
3535

3636
protected:
37-
~NwCurrentWindowInternalCapturePageFunction() override;
37+
~NwCurrentWindowInternalCapturePageInternalFunction() override;
3838

3939
// ExtensionFunction:
4040
bool RunAsync() override;
@@ -44,7 +44,7 @@ class NwCurrentWindowInternalCapturePageFunction : public AsyncExtensionFunction
4444
FAILURE_REASON_VIEW_INVISIBLE
4545
};
4646
virtual void OnCaptureFailure(FailureReason reason);
47-
DECLARE_EXTENSION_FUNCTION("nw.currentWindowInternal.capturePage", UNKNOWN)
47+
DECLARE_EXTENSION_FUNCTION("nw.currentWindowInternal.capturePageInternal", UNKNOWN)
4848

4949
private:
5050
typedef core_api::extension_types::ImageDetails ImageDetails;
@@ -59,7 +59,7 @@ class NwCurrentWindowInternalCapturePageFunction : public AsyncExtensionFunction
5959
// Quality setting to use when encoding jpegs. Set in RunAsync().
6060
int image_quality_;
6161

62-
DISALLOW_COPY_AND_ASSIGN(NwCurrentWindowInternalCapturePageFunction);
62+
DISALLOW_COPY_AND_ASSIGN(NwCurrentWindowInternalCapturePageInternalFunction);
6363
};
6464

6565
} // namespace extensions

src/resources/api_nw_window.js

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@ nw_binding.registerCustomHook(function(bindingsAPI) {
2222
NWWindow.prototype[key] = value;
2323
});
2424

25-
NWWindow.prototype.onNewWinPolicy = new Event();
26-
NWWindow.prototype.onNavigation = new Event();
25+
NWWindow.prototype.onNewWinPolicy = new Event();
26+
NWWindow.prototype.onNavigation = new Event();
27+
NWWindow.prototype.LoadingStateChanged = new Event();
28+
2729
NWWindow.prototype.on = function (event, callback) {
2830
switch (event) {
2931
case 'closed':
3032
this.appWindow.onClosed.addListener(callback);
3133
break;
34+
case 'loaded':
35+
this.LoadingStateChanged.addListener(function(status) { callback(status); });
36+
break;
3237
case 'new-win-policy':
3338
this.onNewWinPolicy.addListener(function(frame, url, policy) {
3439
policy.ignore = function () { this.val = 'ignore'; };
@@ -48,6 +53,28 @@ nw_binding.registerCustomHook(function(bindingsAPI) {
4853
break;
4954
}
5055
};
56+
NWWindow.prototype.capturePage = function (callback, options) {
57+
var cb = callback;
58+
if (!options)
59+
options = {'format':'jpeg', 'datatype':'datauri'};
60+
if (typeof options == 'string')
61+
options = {'format':options, 'datatype':'datauri'};
62+
if (options.datatype != 'datauri') {
63+
cb = function (format, datauri) {
64+
var raw = datauri.replace(/^data:[^;]*;base64,/, '');
65+
switch(format){
66+
case 'buffer' :
67+
callback(new nw.Buffer(raw, "base64"));
68+
break;
69+
case 'raw' :
70+
callback(raw);
71+
break;
72+
}
73+
};
74+
cb = cb.bind(undefined, options.datatype);
75+
}
76+
currentNWWindowInternal.capturePageInternal(options, cb);
77+
};
5178
NWWindow.prototype.eval = function (frame, script) {
5279
nwNatives.evalScript(frame, script);
5380
};
@@ -131,34 +158,36 @@ nw_binding.registerCustomHook(function(bindingsAPI) {
131158
//FIXME: unify this conversion code with nwjs/default.js
132159
options.innerBounds = {};
133160
options.outerBounds = {};
134-
if (params.frame === false)
135-
options.frame = 'none';
136-
if (params.resizable === false)
137-
options.resizable = false;
138-
if (params.x)
139-
options.outerBounds.left = params.x;
140-
if (params.y)
141-
options.outerBounds.top = params.y;
142-
if (params.height)
143-
options.innerBounds.height = params.height;
144-
if (params.width)
145-
options.innerBounds.width = params.width;
146-
if (params.min_width)
147-
options.innerBounds.minWidth = params.min_width;
148-
if (params.max_width)
149-
options.innerBounds.maxWidth = params.max_width;
150-
if (params.min_height)
151-
options.innerBounds.minHeight = params.min_height;
152-
if (params.max_height)
153-
options.innerBounds.maxHeight = params.max_height;
154-
if (params.fullscreen === true)
155-
options.state = 'fullscreen';
156-
if (params.show === false)
157-
options.hidden = true;
158-
if (params['always_on_top'] === true)
159-
options.alwaysOnTop = true;
160-
if (params['visible_on_all_workspaces'] === true)
161-
options.visibleOnAllWorkspaces = true;
161+
if (params) {
162+
if (params.frame === false)
163+
options.frame = 'none';
164+
if (params.resizable === false)
165+
options.resizable = false;
166+
if (params.x)
167+
options.outerBounds.left = params.x;
168+
if (params.y)
169+
options.outerBounds.top = params.y;
170+
if (params.height)
171+
options.innerBounds.height = params.height;
172+
if (params.width)
173+
options.innerBounds.width = params.width;
174+
if (params.min_width)
175+
options.innerBounds.minWidth = params.min_width;
176+
if (params.max_width)
177+
options.innerBounds.maxWidth = params.max_width;
178+
if (params.min_height)
179+
options.innerBounds.minHeight = params.min_height;
180+
if (params.max_height)
181+
options.innerBounds.maxHeight = params.max_height;
182+
if (params.fullscreen === true)
183+
options.state = 'fullscreen';
184+
if (params.show === false)
185+
options.hidden = true;
186+
if (params['always_on_top'] === true)
187+
options.alwaysOnTop = true;
188+
if (params['visible_on_all_workspaces'] === true)
189+
options.visibleOnAllWorkspaces = true;
190+
}
162191
chrome.app.window.create(url, options, function(appWin) {
163192
callback(appWin.contentWindow.nw.Window.get());
164193
});
@@ -190,6 +219,14 @@ function onNavigation(frame, url, policy, context) {
190219
dispatchEventIfExists(currentNWWindow, "onNavigation", [frame, url, policy, context]);
191220
}
192221

222+
function onLoadingStateChanged(status) {
223+
console.log("onLoadingStateChanged: " + status);
224+
if (!currentNWWindow)
225+
return;
226+
dispatchEventIfExists(currentNWWindow, "LoadingStateChanged", [status]);
227+
}
228+
193229
exports.binding = nw_binding.generate();
194230
exports.onNewWinPolicy = onNewWinPolicy;
195-
exports.onNavigation = onNavigation;
231+
exports.onNavigation = onNavigation;
232+
exports.LoadingStateChanged = onLoadingStateChanged;

0 commit comments

Comments
 (0)