Chromium Code Reviews| Index: elements/designer-stage/designer-stage.html |
| diff --git a/elements/designer-stage/designer-stage.html b/elements/designer-stage/designer-stage.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b5cbef75e9ab89abeb5141d33e4fc307ff07df4b |
| --- /dev/null |
| +++ b/elements/designer-stage/designer-stage.html |
| @@ -0,0 +1,160 @@ |
| +<!-- |
| + Copyright 2015 The Polymer Authors. All rights reserved. |
| + Use of this source code is governed by a BSD-style |
| + license that can be found in the LICENSE file. |
| +--> |
| +<!doctype html> |
| +<html> |
| + <head> |
| + <link rel="import" href="../../../polymer/polymer.html"> |
| + <link rel="import" href="../../../neoprene/components/x-elements/x-template/x-template.html"> |
| + <link rel="import" href="../designer-selection/designer-selection.html"> |
|
imac
2015/02/05 01:54:07
I think you forgot to include this in the patch
justinfagnani
2015/02/05 22:15:45
It's in the other CL
|
| + </head> |
| + <body> |
|
imac
2015/02/05 01:54:06
IMO going w/ the `html`-less and `body`-less style
justinfagnani
2015/02/05 22:15:45
Done.
|
| + |
| + <dom-module id="designer-stage"> |
| + <style> |
| + designer-stage { |
| + display: block; |
| + box-sizing: border-box; |
| + } |
| + designer-stage > iframe { |
| + position: absolute; |
| + top: 0; |
| + left: 0; |
| + width: 100%; |
| + height: 100%; |
| + border: none; |
| + box-sizing: border-box; |
| + background: gray; |
| + } |
| + designer-stage > #glass { |
| + position: absolute; |
| + top: 0; |
| + left: 0; |
| + width: 100%; |
| + height: 100%; |
| + z-index: 100; |
| + } |
| + designer-stage > designer-selection { |
| + position: absolute; |
| + z-index: 101; |
| + } |
|
imac
2015/02/05 01:54:07
You may want pointer-events: none; on this guy (bu
justinfagnani
2015/02/05 22:15:45
no, the selector needs events.
|
| + </style> |
| + <template> |
| + <designer-selection id="selection"></designer-selection> |
| + <div id="glass" on-mousedown="_onMouseDown"></div> |
| + <!-- |
| + Note: src is main document relative, and only works in the demo |
| + because it's in the same directory as this file. Need to solve this. |
| + --> |
| + <iframe id="frame" src="frame.html" sandbox="allow-scripts"></iframe> |
| + </template> |
| + </dom-module> |
| + <script> |
| + Polymer({ |
| + is: 'designer-stage', |
| + |
| + created: function() { |
| + this.token = null; |
| + }, |
| + |
| + ready: function() { |
| + window.addEventListener('message', this._onMessage.bind(this)); |
| + this.$.selection.addEventListener('designer-selection-resize', |
| + this._onSelectionResize.bind(this)); |
| + var frame = this.$.frame; |
| + var token = this.token = this._generateToken(); |
| + frame.onload = function() { |
|
imac
2015/02/05 01:54:06
Hey, use `addEventListener` here! I don't have a r
imac
2015/02/05 01:54:07
Seems like there's a potential race here too: coul
justinfagnani
2015/02/05 22:15:45
Done.
justinfagnani
2015/02/05 22:15:45
In that case I'm unsure how to know the content is
imac
2015/02/06 20:29:49
Hmm, could post a message to it and hope for a res
justinfagnani
2015/02/06 23:49:42
I'll test in polyfill land. I suspect the setup an
|
| + frame.contentWindow.postMessage({ |
| + message_type: 'setToken', |
| + token: token |
| + }, '*'); |
| + }; |
|
imac
2015/02/05 01:54:06
Don't forget to handle the `error` event!
justinfagnani
2015/02/05 22:15:45
Done.
|
| + }, |
| + |
| + _generateToken: function() { |
| + var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; |
| + var token = ''; |
| + for (var i = 0; i < 16; i++) { |
| + token += alphabet.charAt(Math.floor(Math.random() * alphabet.length)); |
| + } |
| + return token; |
| + }, |
|
imac
2015/02/05 01:54:06
Are you aiming for a UUID here, or just something
justinfagnani
2015/02/05 22:15:45
Just reasonably unique. I can use crypto soon I gu
|
| + |
| + _onMessage: function(e) { |
| + if (e.data.token != this.token) { |
| + throw new Error('Invalid token'); |
|
imac
2015/02/05 01:54:07
Stick the name of the token in that error message
justinfagnani
2015/02/05 22:15:45
Done.
|
| + } |
| + |
| + switch (e.data.message_type) { |
| + case 'updateSelector': |
| + this._updateSelector(e); |
| + break; |
| + case 'seletedElement': |
| + this._selectedElement(e); |
| + break; |
| + } |
|
imac
2015/02/05 01:54:06
As this grows, consider moving to a lookup table
justinfagnani
2015/02/05 22:15:45
Acknowledged.
|
| + }, |
| + |
| + _updateSelector: function(e) { |
| + var bounds = e.data.bounds; |
| + var style = this.$.selection.style; |
| + if (bounds == null) { |
| + style.display = 'none'; |
| + } else { |
| + style.display = 'block'; |
| + style.top = bounds.top; |
| + style.left = bounds.left; |
| + style.width = bounds.width; |
| + style.height = bounds.height; |
|
imac
2015/02/05 01:54:07
Probably want to clamp these to stay within the st
justinfagnani
2015/02/05 22:15:44
This is just a very rough start, I also need to va
|
| + } |
| + }, |
| + |
| + _selectedElement: function(e) { |
| + var data = e.data; |
| + var bounds = data.bounds; |
|
imac
2015/02/05 01:54:07
`data` can be null here
justinfagnani
2015/02/05 22:15:45
I'm going to trust messages from myself for now, e
|
| + var selection = this.$.selection; |
| + var style = selection.style; |
| + if (data.position == 'static') { |
| + selection.directions = ResizeDirection.width_height; |
|
imac
2015/02/05 01:54:07
Where is `ResizeDirection` coming from?
justinfagnani
2015/02/05 22:15:45
Loaded with designer-selection. I'll modularize so
|
| + } else if (data.position == 'static') { |
| + selection.directions = ResizeDirection.all_directions; |
| + } |
| + // TODO: factor out common code with _updateSelector. |
| + // Possibly implement message batching or extension. |
|
imac
2015/02/05 01:54:07
Damn right you'll factor that out!
justinfagnani
2015/02/05 22:15:45
Acknowledged! :)
|
| + if (bounds == null) { |
| + style.display = 'none'; |
| + } else { |
| + style.display = 'block'; |
| + style.top = bounds.top; |
| + style.left = bounds.left; |
| + style.width = bounds.width; |
| + style.height = bounds.height; |
| + } |
| + }, |
| + |
| + _onSelectionResize: function(e) { |
| + var frame = this.$.frame; |
| + |
| + frame.contentWindow.postMessage({ |
| + message_type: 'resizeElement', |
| + bounds: e.detail |
| + }, '*'); |
|
imac
2015/02/05 01:54:06
Might be good to use an actual origin. What if an
justinfagnani
2015/02/05 22:15:45
I'm not sure what origin to put, since a sandboxed
imac
2015/02/06 20:29:49
Oh, sandboxed iframes prevent navigation? Neat!
justinfagnani
2015/02/06 23:49:42
And popups, pointer-locks and a few other things..
|
| + |
| + }, |
| + |
| + _onMouseDown: function(e) { |
| + var frame = this.$.frame; |
| + |
| + frame.contentWindow.postMessage({ |
| + message_type: 'selectElement', |
|
imac
2015/02/05 01:54:07
IMO you should do the dreaded ##ms debounce here,
justinfagnani
2015/02/05 22:15:45
What wrong with selecting on every click?
imac
2015/02/06 20:29:49
That works too! I was expecting the selection visu
justinfagnani
2015/02/06 23:49:43
Acknowledged.
|
| + x: e.clientX, |
| + y: e.clientY |
|
imac
2015/02/05 01:54:07
You should probably translate these relative to `f
justinfagnani
2015/02/05 22:15:45
Adding todo. I need some test where client bounds
|
| + }, "*"); |
| + } |
| + |
| + }); |
| + </script> |
| + </body> |
| +</html> |