how to determine if the browser supports selectionStart if there is no text selected - dom

This code will return true if the browser supports selectionStart and some text is selected, but if no text is selected it returns false (even on browsers that support it):
if (el.selectionStart) {
}
How do you determine if the property is available regardless of whether text happens to be selected?
Thanks

Further googling revealed the answer:
if (el.selectionStart != undefined) {
}

Hopefully this will help you. I tested it on an old Android 4.2 (which returns false) and Chrome (which returns true).
function selectionSupport() {
var input = document.createElement("input");
input.setAttribute('value', '111');
input.selectionStart = 1;
input.selectionEnd = 2;
return (input.selectionStart === 1 && input.selectionEnd === 2);
}
var selectionIsSupported = selectionSupport();

Related

UI5: Validate Whole Form's Required and Visible Fields for Null/Blank Values

onPress of submit button, I want to validate all SimpleForms' fields (ComboBox, Input, DatePicker, etc.) that are
required &
visible
to see if they are null or blank (""). If a targeted (required & visible) field is null/blank, set that control's state to "Error" and display an error message. If no targeted field is null/blank, pop up a success dialog box.
This method is automated so in the future, any fields added later will automatically be checked without need of manual additions to controller code.
Controller code:
requiredAndVisible: function(oControl) {
if (typeof oControl.getRequired === "function") { //certain ctrls like toolbars dont have getRequired as a method, so we want to skim those out, else itll throw an error later in the next check
if (oControl.getRequired() === true && oControl.getVisible() === true) {
return oControl;
}
}
},
onSubmit: function() {
var valid = true,
oView = this.getView(),
aFormInitial = oView.byId("formInitial").getContent(), // get all the controls of SimpleForm1
aFormConfig = oView.byId("formConfiguration").getContent(), // get all controls of SimpleForm2
aControls = aFormInitial.concat(aFormConfig), // combine the 2arrays together into 1
aFilteredControls = aControls.filter(this.requiredAndVisible); // check each element if it required & visible using the 1st function. return only the controls that are both req'd & visible
aFilteredControls.forEach(function(oControl) { // in resultant array, check each element if...
if (!oControl.getValue() || oControl.getValue().length < 1) { // its value is null or blank
oControl.setValueState("Error");
valid = false; // set valid to false if it is
} else {
oControl.setValueState("None");
}
});
if (valid === false) {
// **replace this code with w/e error handling code u want**
oView.byId("errorMsgStrip").setVisible(true);
} else if (valid === true) {
// **replace this code with whatever success handling code u want**
var oDialogConfirm = new sap.ui.xmlfragment("dialogID", "dialog.address.here", this);
oDialogConfirm.open();
}
},

JSX/Photoshop: Toggling non selected layer visibility by name?

I'm using this piece for hide/show selected layer:
app.activeDocument.activeLayer.visible = !app.activeDocument.activeLayer.visible;
I wonder if there exist a way of toggling a non selected layer by it's name.
Many thanks
Update:
I got it working with this thing (I know, it must be cleaned):
function toggleLayer() {
for( var i = 0; i < app.activeDocument.artLayers.length; i++) {
if (app.activeDocument.artLayers[i].name == "theLayer"){
app.activeDocument.artLayers[i].allLocked = false;
app.activeDocument.artLayers[i].visible = !app.activeDocument.artLayers[i].visible;
}
}
}
I'd like to know if we can do the same without the loop.
Thanks
Here is the solution I did write. Unexpectedly it worked :P
function toggleLayer() {
var tl = app.activeDocument.layers["theLayer"];
tl.visible = !tl.visible;
}
toggleLayer();
Now, I have another doubt: Whats the difference between "layers" and "artLayers"?
Cheers

Protractor: accessing capabilities

I am running with multiCapabilities, and would like to know if it is possible to know what capability is currently used, both in the onPrepare function and/or the testcase itself.
The use case is that I am planning to run my tests both on chrome and on android. For Chrome the window should be resized to required dimensions, however running the same code on selendroid gives an exception because the method is not implemented (also resizing a window on a device does not really make sense):
So, the idea was to somehow wrap the offending code in a simple check like so:
if(browser != 'android')
browser.driver.manage().window().setSize(480, 800);
There are also other use cases, but that's the most important one for now.
I do stuff like that within the onPrepare section, e.g.
// Return if current browser is IE, optionally specifying if it is a particular IE version
browser.isInternetExplorer = function(ver) {
var browserName, version, ie;
return browser.getCapabilities().then(function(s) {
browserName = s.caps_.browserName;
version = s.caps_.version;
ie = /i.*explore/.test(browserName);
if (ver == null) {
return ie;
} else {
return ie && ver.toString() === version;
}
});
};
Then, later on, i use it like this:
if (browser.isInternetExplorer()) {...}
For android this should work:
browser.isAndroid = function(ver) {
var browserName, version;
return browser.getCapabilities().then(function(s) {
browserName = s.caps_.browserName;
version = s.caps_.version;
return /droid/.test(browserName);
});
};

forced_root_block option in TinyMCE

I am trying to implement a custom WYSIWYG editor using a contenteditable <div>.
One of the major issues I am facing is the inconsistent way browsers handle ENTER keystroke (linebreaks). Chrome inserts <div>, Firefox inserts <br> and IE inserts <p>. I was taking a look at TinyMCE and it has a configuration option called forced_root_block. Setting forced_root_block to div actually works across all major browser. Does someone know how forced_root_block option in TinyMCE is able to achieve it across browsers ?
In the tinymce source (/tiny_mce/classs/dom/DomParser.js) you will find the following:
rootBlockName = "forced_root_block" in args ? args.forced_root_block : settings.forced_root_block;
whiteSpaceElements = schema.getWhiteSpaceElements();
startWhiteSpaceRegExp = /^[ \t\r\n]+/;
endWhiteSpaceRegExp = /[ \t\r\n]+$/;
allWhiteSpaceRegExp = /[ \t\r\n]+/g;
function addRootBlocks() {
var node = rootNode.firstChild, next, rootBlockNode;
while (node) {
next = node.next;
if (node.type == 3 || (node.type == 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type'))) {
if (!rootBlockNode) {
// Create a new root block element
rootBlockNode = createNode(rootBlockName, 1);
rootNode.insert(rootBlockNode, node);
rootBlockNode.append(node);
} else
rootBlockNode.append(node);
} else {
rootBlockNode = null;
}
node = next;
};
};
This obviously takes care of creating root block elements.
I am 99% sure that tinymce handles the 'ENTER' keystroke itself and stops the propagation/ default browser command.

Make Webview's auto links visible

A Webview will display links in the content HTML as having blue underlines. So if you have something in the HTML like
blah blah
... it is clearly visible as a link.
The Webview also allows you to click on phone numbers and addresses (even if those are just text in the HTML, not links) to launch the Dialer or Maps.
How can one get Webview to display those (Linkify, probably) links with underlines etc? It's easy enough in a TextView since one can get the spans from a TextView and style them, but Webview doesn't expose any way to retrieve that data... at least not that I can see looking through the docs.
Here is some JS code which can be injected to linkify phone numbers, emails and urls:
function linkify() {
linkifyTexts(linkifyPhoneNumbers);
linkifyTexts(linkifyEmails);
linkifyTexts(linkifyWebAddresses1);
linkifyTexts(linkifyWebAddresses2);
}
function linkifyPhoneNumbers(text) {
text = text.replace(/\b\+?[0-9\-]+\*?\b/g, '$&');
return text;
}
function linkifyEmails(text) {
text = text.replace(/(\w+#[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim, '$1');
return text;
}
function linkifyWebAddresses1(text) {
text = text.replace(/(\b(https?|ftp):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/gim, '$1');
return text;
}
function linkifyWebAddresses2(text) {
text = text.replace(/(^|[^\/])(www\.[\S]+(\b|$))/gim, '$1$2');
return text;
}
var linkifyTexts = function(replaceFunc)
{
var tNodes = [];
getTextNodes(document.body,false,tNodes,false);
var l = tNodes.length;
while(l--)
{
wrapNode(tNodes[l], replaceFunc);
}
}
function getTextNodes(node, includeWhitespaceNodes,textNodes,match) {
if (node.nodeType == 3) {
if (includeWhitespaceNodes || !/^\s*$/.test(node.nodeValue)) {
if(match){
if(match.test(node.nodeValue))
textNodes.push(node);
}
else {
textNodes.push(node);
}
}
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
var subnode = node.childNodes[i];
if (subnode.nodeName != "A") {
getTextNodes(subnode,includeWhitespaceNodes,textNodes,match);
}
}
}
}
function wrapNode(n, replaceFunc) {
var temp = document.createElement('div');
if(n.data)
temp.innerHTML = replaceFunc(n.data);
else{
//whatever
}
while (temp.firstChild) {
n.parentNode.insertBefore(temp.firstChild,n);
}
n.parentNode.removeChild(n);
}
Given this:
http://code.google.com/p/android/issues/detail?id=742
it still doesn't seem to be a way to do this from Java directly. One thing that might work is to write some JavaScript code and run it after page is loaded, e.g. as given here:
In Android Webview, am I able to modify a webpage's DOM?
Here's an example of a similar thing:
Disabling links in android WebView
where the idea is to disable links. You may be able to use a similar approach to add some CSS, including underlining. A couple of other SOqs / links that might help:
Android: Injecting Javascript into a Webview outside the onPageFinished Event
Android: Injecting Javascript into a Webview outside the onPageFinished Event
http://iphoneincubator.com/blog/windows-views/how-to-inject-javascript-functions-into-a-uiwebview
Injecting Javascript into a Webview outside the onPageFinished Event (Using DatePicker to set a date on an input of a WebView)
Hope this helps.