addEventListener on youtube API with greasemonkey - youtube

I would like to use Greasemonkey to access some API objects of youtube videos while I'm in fullscreen mode.
It could be useful to have mouse clicks and position relative to screen.
This, to detect fullscreen mode, doesn't work:
window.fullScreen
I tried also to add mouse event detection to yt player, with this:
var player = document.getElementById('movie_player');
player.addEventListener("click", interceptClicks,true);
but it doesn't fire that func.
I tried also to inject some code like this:
function GM_main () {
var playerNode = document.getElementById ("movie_player");
playerNode.addEventListener ('click', interceptClicks ,false);
}
addJS_Node (null, null, GM_main);
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
I tried also to make a:
window.addEventListener('click', interceptClicks, false);
This works, BUT only in all areas different from the youtube flash player in non-fullscreen mode and in fullscreen mode, obviously none area, as there is only the player visible...
EDIT:
I made a partial progress indeed.
I created a button element with
btn.addEventListener("click", function () { player.mozRequestFullScreen();}, false)
This way flash video enters in Firefox fullscreen mode and so it receives the wheel events fired by the
window.addEventlistener('DOMMouseScroll', .....etc)
Besides, the fullscreen mode is detected by
window.fullScreen
Also, all keys (event) are detectable, but ESC; not again the mouse clicks..
There is a drawback:
Once in fullscreen, SOMETIMES if you click the left mouse button it suddenly exits fullscreen mode... SOMETIMES instead it stays normally full...
To exit it's not sufficient to press ESC, you need to press the normal flash fullscreen button on the lower right + ESC.
Some rare times it blocks itself in Fullscreen mode and you can't exit. You should press ctrl+alt+canc and then it appears firefox "block script" dialog box.
Why that odd behaviour and how to prevent it?
Ideally the best should be: intercept mouse click on the lower right flash fullscreen button, block it, redirect the call to mozFullscreen and block the fullscreen mode until you press ESC.
But I dont' think it's possible, is it?

Related

YTPlayerView controls settings don't affect fullscreen mode

I'm trying to play a youtube video in my iOS app using "YTPlayerView".
My aim is to play video in fullscreen, don't show any controls, and close it on the first tap to the screen.
If I play video inline, everything works properly, but in fullscreen control-bars appear. However, if I close fullscreen with its button (on the bottom right), controls disappear.
var playerVars = [AnyHashable : Any]()
playerVars["enablejsapi"] = 1
playerVars["rel"] = 0
playerVars["fs"] = 0
playerVars["controls"] = 0
playerVars["iv_load_policy"] = 3
playerVars["modestbranding"] = 1
playerVars["playsinline"] = 0
playerVars["showinfo"] = 0
self.playerView.load(withVideoId: videoId, playerVars: playerVars)
Any help will be very appreciated to solve this issue.
Image about full screen with control-bars
"rel" and "info" depricated. Try this -
"playsinline"
This parameter controls whether videos play inline or fullscreen in an HTML5 player on iOS. Valid values are:
0: This value causes fullscreen playback. This is currently the default value, though the default is subject to change.
1: This value causes inline playback for UIWebViews created with the allowsInlineMediaPlayback property set to TRUE.

Scrolling <div> in iOS causes div to blank out

I'm trying to handle a long list of <div>s and maintain scroll position in the list after navigating off and coming back. Essentially when a selection made is in the list I capture the listScrollPos and then try to reset it when I'm returning to the page (in Angular - so the list is re-rendered first).
vm.getAlbums = function() {
albumService.getAlbums()
.success(function (data) {
vm.albums = data;
$timeout(function () {
if (albumService.listScrollPos) {
$("#MainView").scrollTop(albumService.listScrollPos);
albumService.listScrollPos = 0;
}
}, 50); // delay required
})
.error(function(err) {
vm.error.error(err.message);
});
};
The process works fine in all browsers I tested - except on iOS in a WebView (Safari works fine). In other browsers the list displays and the scroll position is moved after the initial render. The pointer resets and all is good.
However, on iOS 8 either in Safari or a Web View in Cordova, the div turns white and shows 'empty'. If I touch the div anywhere it immediately displays at the correct scroll position.
IOW, the DOM appears to be updated and rendered, but the browser is somehow optimizing the scrolled content that was moved under program control.
Is there any way to force the browser to re-render the element after the scroll position was moved programmatically?
Ok, so after a bit more checking the problem is definitely isolated to the iOS WebView - Safari on iOS works fine without any of the following. But a Cordova app or a pinned iOS app exhibits this 'white out' behavior.
The workaround is to explicitly force the DOM to re-render the element using the 'scrollHeight reading trick'.
Here's the code that works:
vm.getAlbums = function() {
albumService.getAlbums()
.success(function (data) {
vm.albums = data;
setTimeout(function () {
if (albumService.listScrollPos) {
var el = $("#MainView");
el.scrollTop(albumService.listScrollPos);
albumService.listScrollPos = 0;
$timeout(function() {
var t = el[0].scrollHeight;
}, 1);
}
}, 1); // delay around animation 900
})
};
Notice the last $timeout() block that simply reads the scrollHeight of the element, which forces the re-render and properly displays the result.
There's a little jumpiness due to the slight rendering delay.

getting mouse click screenX and screenY in as3

I want to get mouse click screen coordinates (by clicking outside AIR application window)
I tried the following, but i don't get anything, it seem like the ScreenMouseEvent.CLICK event not dispatched.
public function Main():void
{
if (NativeApplication.supportsSystemTrayIcon)//testExpression return true
{
SystemTrayIcon(NativeApplication.nativeApplication.icon).
addEventListener(ScreenMouseEvent.CLICK, click);
}
}
private function click(e:ScreenMouseEvent):void
{
trace(e.screenX);//nothing displayed :(
}
The ScreenMouseEvent is dispatched by the SystemTrayIcon only (Windows/Linux only). And the SystemTrayIcon instance (DockIcon for MacOs) is retrieved from NativeApplication.nativeApplication.icon.
So this is where you should attach your event listener, after specifying the tray icon graphic:
var sti:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon;
// Specifying an icon is obligatory on Windows - MacOs has a default icon
sti.bitmaps = [new IconAsset()]; // IconAsset = Embedded picture
sti.addEventListener(ScreenMouseEvent.CLICK, mouseClick);
Note that the resultant screenX and screenY properties of ScreenMouseEvent are confined within the icon area in the tray and not the whole desktop screen (Not surprisingly, since this is where you added the event in the first place).

fixed position div freezes on page (iPad)

I have an asp.net web site I am building to be supported on ipad. When I focus on an input element and the keyboard pops up, the position fixed header div(which normally scrolls along with the page) will pop up the page a distance equivalent to the amount the keyboard takes up and freeze there for the duration of the input process. Once the keyboard is dropped back down, the div snaps back into place and behaves normally again. I am testing on iOS5 so position: fixed should be supported.
Is this a known issue? Has someone come across this and dealt with it before? I can't seem to find anything on this.
Fixed positioning is broken on iOS5/iOS6/iOS7.
Edit 3: See link to a working fix near end of this answer for iOS8.
Position:fixed is broken when either:
a) the page is zoomed
or
b) the keyboard shows on the iPad/iPhone (due to an input getting focus).
You can view the bugs yourself in jsbin.com/icibaz/3 by opening the link and zooming, or giving the input focus. You can edit the edit the html yourself.
Notes about bugs (a) and (b):
A fixed div with top: 0px; left: 0px; will show in the wrong position (above or below the top of the screen) when an input gets focus and the keyboard shows.
The problem seems to have something to do with the auto-centering of the input on the screen (changing window.pageYOffset).
It appears to be a calculation fault, and not a redraw fault: if you force the top: to change (e.g. switching between 0px and 1px) on the onScroll event, you can see the fixed div move by a pixel, but it remains in the wrong place.
One solution I used previously is to hide the fixed div when an input gets focus - see the other Answer I wrote.
The fixed div seems to becomes stuck at the same absolute position on the page it was at at the time when the keyboard opened.
So perhaps change the div to absolute positioning when an input has focus? Edit 3: see comment at bottom using this solution. Or perhaps save the pageXOffset/pageYOffset values before the keyboard is opened, and in an onScroll event calculate the difference between those values and the current pageXOffset/pageYOffset values (current once the keyboard is opened), and offset the fixed div by that difference.
There appears to be a different problem with fixed positioning if the page is zoomed - try it here (Also good information here about Android support for fixed in comments).
Edit 1: To reproduce use jsbin (not jsfiddle) and use the fullscreen view of jsbin (not the edit page). Avoid jsfiddle (and edit view of jsbin) because they put the code inside an iframe which causes interference with fixed positioning and pageYOffset.
Edit 2: iOS 6 and iOS 7 Mobile Safari position:fixed; still has the same issues - presumably they are by design!.
Edit 3: A working solution for (b) is when the input get focus, change the header to absolute positioning and then set the header top on the page scroll event for example. This solution:
Uses fixed positioning when input not focused (using window.onscroll has terrible jitter).
Don't allow pinch-zoom (avoid bug (a) above).
Uses absolute positioning and window.pageYOffset once an input gets focus (so header is correctly positioned).
If scrolled while input has focus, set style.top to equal pageYOffset (header will jitter somewhat due to onscroll event delay even on iOS8).
If using UIWebView within an App on iOS8, or using <=iOS7, if scrolling when input has focus, header will be super jittery because onscroll is not fired till scroll finishes.
Go back to fixed position header once input loses focus (Example uses input.onblur, but probably tider to use
document.body.onfocus).
Beware usability fail that if header too large, the input can be occluded/covered.
I couldn't get to work for a footer due to bugs in iOS page/viewport height when the keyboard is showing.
Edit example using http://jsbin.com/xujofoze/4/edit and view using http://output.jsbin.com/xujofoze/4/quiet
For my needs, I found it easier to use an absolute positioned header, hide it before scroll and show it when finish scroll (I need the same code to support iOS4 and Android).
For my purposes, I hide the header on a touchstart event, and show it again on touchend or scroll event (plus some timers to improve responsiveness/reduce flickering). It flashes, but is the best compromise I could find. One can detect the start of scrolling using the touchmove event (jQuery does this), but I found touchmove didn't work as well for me because:
regularly the iPad fails to do a repaint before scrolling (i.e. the absolute header remains stuck - even though the top was changed before scrolling started).
when an input element gets focus, the iPad auto-centres the element, but the scrollstart event doesn't get fired (because no touchmove if just clicking an input).
Implementing a fixed header on iOS5 could be improved by using a hybrid approach of fixed and absolute positioning:
used fixed positioning for iOS5 until an input gets focus.
when an input gets focus (keyboard showing), change to the iOS4 absolute positioning code.
when the keyboard is closed, change back to fixed positioning.
Code to detect when keyboard is closed (e.g. using keyboard hide key) is to register the DOMFocusOut event on the document element and do something like the following code. The timeout is needed because the DOMFocusOut event can fire between when one element gets the focus and another loses it.
function document_DOMFocusOut() {
clearTimeout(touchBlurTimer);
touchBlurTimer = setTimeout(function() {
if (document.activeElement == document.body) {
handleKeyboardHide();
}
}.bind(this), 400);
}
My fixed header code is something like:
{
setup: function() {
observe(window, 'scroll', this, 'onWinScroll');
observe(document, 'touchstart', this, 'onTouchStart');
observe(document, 'touchend', this, 'onTouchEnd');
if (isMobile) {
observe(document, 'DOMFocusOut', this, 'docBlurTouch');
} else if (isIE) {
// see http://ajaxian.com/archives/fixing-loss-of-focus-on-ie for code to go into this.docBlurIe()
observe(document, 'focusout', this, 'docBlurIe');
} else {
observe(isFirefox ? document : window, 'blur', this, 'docBlur');
}
},
onWinScroll: function() {
clearTimeout(this.scrollTimer);
this.scrolling = false;
this.rehomeAll();
},
rehomeAll: function() {
if ((isIOS5 && this.scrolling) || isIOS4 || isAndroid) {
this.useAbsolutePositioning();
} else {
this.useFixedPositioning();
}
},
// Important side effect that this event registered on document on iOs. Without it event.touches.length is incorrect for any elements in the document using the touchstart event!!!
onTouchStart: function(event) {
clearTimeout(this.scrollTimer);
if (!this.scrolling && event.touches.length == 1) {
this.scrolling = true;
this.touchStartTime = inputOrOtherKeyboardShowingElement(event.target) ? 0 : (new Date).getTime();
// Needs to be in touchStart so happens before iPad automatic scrolling to input, also not reliable using touchMove (although jQuery touch uses touchMove to unreliably detect scrolling).
this.rehomeAll();
}
},
onTouchEnd: function(event) {
clearTimeout(this.scrollTimer);
if (this.scrolling && !event.touches.length) {
var touchedDuration = (new Date).getTime() - this.touchStartTime;
// Need delay so iPad can scroll to the input before we reshow the header.
var showQuick = this.touchStartTime && touchedDuration < 400;
this.scrollTimer = setTimeout(function() {
if (this.scrolling) {
this.scrolling = false;
this.rehomeAll();
}
}.bind(this), showQuick ? 0 : 400);
}
},
// ... more code
}
jQuery mobile supports scrollstart and scrollstop events:
var supportTouch = $.support.touch,
scrollEvent = "touchmove scroll",
touchStartEvent = supportTouch ? "touchstart" : "mousedown",
touchStopEvent = supportTouch ? "touchend" : "mouseup",
touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
function triggerCustomEvent( obj, eventType, event ) {
var originalType = event.type;
event.type = eventType;
$.event.handle.call( obj, event );
event.type = originalType;
}
// also handles scrollstop
$.event.special.scrollstart = {
enabled: true,
setup: function() {
var thisObject = this,
$this = $( thisObject ),
scrolling,
timer;
function trigger( event, state ) {
scrolling = state;
triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
}
// iPhone triggers scroll after a small delay; use touchmove instead
$this.bind( scrollEvent, function( event ) {
if ( !$.event.special.scrollstart.enabled ) {
return;
}
if ( !scrolling ) {
trigger( event, true );
}
clearTimeout( timer );
timer = setTimeout(function() {
trigger( event, false );
}, 50 );
});
}
};
This is somewhat still a problem in iOS13 (when a long text gets deleted in the 'textarea' field, fixed header jumps to the start of that 'textarea' field, obstructing the view), therefore, I thought I share my quick fix:
Since my footer is rather large, I went about without any JS and just adding a greater z-index to the footer than what the fixed header has. Out of sight, out of mind.

Dojo dialog, the iPad and the virtual keyboard issue

Recently, I have been working on a project where the interface should work for desktop and tablets (in particular the iPad).
One issue I am coming across is with a Dojo dialog on the iPad when text entry is taking place.
Basically here is what happens:
Load Dojo interface with buttons on iPad - OK
Press button (touch) to show dialog (90% height and width) - OK
Click on text box (touch) like DateTextBox or TimeTextBox - OK, the virtual keyboard is opened
Click the date or time I want in the UI (touch) - OK, but I can't see all of the options since it is longer than the screen size...
Try to scroll down (swipe up with two fingers or click 'next' in the keyboard) - not OK and the dialog repositions itself to have it's top at the top of the viewport area.
Basically, the issue is that the dialog keeps trying to reposition itself.
Am I able to stop dialog resizing and positioning if I catch the window onResize events?
Does anyone else have this issue with the iPad and Dojo dialogs?
Also, I found this StackOverflow topic on detecting the virtual keyboard, but it wasn't much help in this case...
iPad Web App: Detect Virtual Keyboard Using JavaScript in Safari?
Thanks!
I just came across the same issue yesterday and found a hack,
which is not an elegant solution.
If you want to stop the dijit.Dialog from repositioning you can:
1) Set the property ._relativePosition of a dijit.Dialog object
(in this case it's "pop") after calling the method pop.show():
pop.show();
pop._relativePosition = new Object(); //create empty object
Next steps would probably be:
Check browser type&OS: dojo or even better BrowserDetect
Check when the virtual keyboard is activated and disable repositioning
Extend dijit.Dialog with custom class (handle all of the exceptions)
As suggested another way to do this is to override the _position function by extending the object (or maybe relative position, or other method). Here is my solution which only allows the dialog to be positioned in the middle of the screen once. There are probably better ways to change this by playing with the hide and show events but this suits my needs.
dojo.provide("inno.BigDialog");
dojo.require("dijit.Dialog");
dojo.declare("inno.BigDialog",dijit.Dialog,{
draggable:false,
firstPositioned : false,
_position : function() {
if (!dojo.hasClass(dojo.body(), "dojoMove") && !this.firstPositioned) {
this.firstPositioned = true;
var _8 = this.domNode, _9 = dijit.getViewport(), p = this._relativePosition, bb = p ? null
: dojo._getBorderBox(_8), l = Math
.floor(_9.l
+ (p ? p.x : (_9.w - bb.w) / 2)), t = Math
.floor(_9.t
+ (p ? p.y : (_9.h - bb.h) / 2));
if (t < 0) // Fix going off screen
t = 0;
dojo.style(_8, {
left : l + "px",
top : t + "px"
});
}
}
});
You can override the _position function and call the _position function of the superclass only once. (See http://dojotoolkit.org/reference-guide/dojo/declare.html#calling-superclass-methods)
if (!dojo._hasResource["scorll.asset.Dialog"]) {
dojo._hasResource["scorll.asset.Dialog"] = true;
dojo.provide("scorll.asset.Dialog");
dojo.require("dijit.Dialog");
dojo.declare("scorll.asset.Dialog", [dijit.Dialog], {
_isPositioned: false,
_position: function () {
if(this._isPositioned == false) {
// Calls the superclass method
this.inherited(arguments);
this._isPositioned = true;
}
}
})
}

Resources