1

I have a webapp I frequently use, which have such kind of forms:

<form method=POST action=...>
  <input type=text name=urname placeholder=urname>
  <input type=text name=secretid placeholder=secretid>
  <input type=text name=otherfield placeholder=otherfield>
  <input type=submit>
</form>

What I want to do is to be able to autofill those fields with specified values (e.g.: urname=kristian, secretid=abcdefghijkl, otherfield=000111222333444555666777888999).

Currently I do it by opening "note" app then copy-pasting its content each time, which can get tedious since it's quite long and I have to go back and forth 3 times. Also, the content of the autofill input is not exactly a secret.

Is there a way to do it?

I found a question with similar problem on Super User: Autofill web forms (but instead of Chrome on PC I want to do it in Chrome in Android). The comments seems to recommend a Cchrome extension that can inject JavaScript into the page. I don't mind that, I can write JS, but I don't think Chrome extensions are available on Android.

EDIT: I found here that I can execute bookmarked JS via chrome without extensions here: How can a bookmarklet be ADDED on mobile Chrome without copying and pasting?

So I made a bookmark with such content:

javascript:(function(){ document.querySelector(`#urname`).value=`kristian`; document.querySelector(`#secretid`).value=`abcdefghijkl` ; document.querySelector(`#otherfield`).value=`000111222333444555666777888999` ; })()

Which if it gets prettified/formatted it will looks like:

javascript:(function(){
  document.querySelector(`#urname`).value=`kristian`;
  document.querySelector(`#secretid`).value=`abcdefghijkl` ;
  document.querySelector(`#otherfield`).value=`000111222333444555666777888999` ; 
})()

But I still have problem: the page seems to use some kind of data binding (e.g.: react two-way binding). So when the value got changed via JS, when I click on the element it goes back to its old (empty) value. Now, how should I circumvent it?

1 Answer 1

0

After some research and digging github issues, here is my own solution:

In general I have to do:

  1. inject custom/self-written JS to chrome android
  2. figure out why it didn't work and the element value changes back to its old / empty value
  3. call correct function so 'react' framework can change the input element AND its internal / 2-way binded data

First step: inject custom/self-written JS to chrome android

From this question: How can a bookmarklet be ADDED on mobile Chrome without copying and pasting? I learned that I can add custom JavaScript to bookmark in chrome

First step cleared

Second step: figure out why it didn't work and the element value changes back to its old / empty value

First look, wonder why the value was not changed even after injecting code like:

document.querySelector(`#otherfield`).value=`000111222333444555666777888999` ; 

So I suspected if it used some kind of JavaScript framework to do 2-way data binding (bind a variable value with an input element).

To detect which framework they used, I installed this extension: Library Detector https://chrome.google.com/webstore/detail/library-detector/cgaocdmhkmfnkdkbnckgmpopcbpaaejo (disclaimer: I'm not associated with the author of said extension)

The result: they used react.js

So, the reason why it didn't work and the element value changes back to its old / empty value is because it used react 2-way data binding

Second step cleared

Third step: call correct function so 'react' framework can change the input element AND its internal / 2-way binded data

After some googling, I find this github issue: https://github.com/facebook/react/issues/11488 which links to this issue comment: https://github.com/facebook/react/issues/10135#issuecomment-314441175

Basically the solution is to call such function:

function setNativeValue(element, value) {
  const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
  const prototype = Object.getPrototypeOf(element);
  const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
  if (valueSetter && valueSetter !== prototypeValueSetter) {
    prototypeValueSetter.call(element, value);
  } else {
    valueSetter.call(element, value);
  }
}

setNativeValue(textarea, 'some text');
textarea.dispatchEvent(new Event('input', { bubbles: true }));

After changing my JS to

function setNativeValue(element, value) {
  const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
  const prototype = Object.getPrototypeOf(element);
  const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
  
  if (valueSetter && valueSetter !== prototypeValueSetter) {
    prototypeValueSetter.call(element, value);
  } else {
    valueSetter.call(element, value);
  }
}

var element1 = document.querySelector(`#urname`);
setNativeValue(element1, `kristian`);
element1.dispatchEvent(new Event('input', { bubbles: true }));

var element2 = document.querySelector(`#secretid`);
setNativeValue(element2, `abcdefghijkl`);
element2.dispatchEvent(new Event('input', { bubbles: true }));

var element3 = document.querySelector(`#otherfield`);
setNativeValue(element3, `000111222333444555666777888999`);
element3.dispatchEvent(new Event('input', { bubbles: true }));

And then enclosing them in

javascript:(function(){  ...  })()

Now it works perfectly

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .