firefox - Find text (ISBN) on page and attach link on it in JS -


for browser (firefox) addon need find isbn's on pages (such as: amazon.com, book.com).

i need find dom elemets containing isbn , manipulate them link, sends isbn rest webservice further logic.

since i'm new javascript don't have idea how because homepages differ in how display isbn.

this current implementation:

var self = require("sdk/self");  // dummy function, show how tests work. // see how test function, @ test/test-index.js function dummy(text, callback) {   callback(text); }  exports.dummy = dummy;  var tag = "body" var buttons = require('sdk/ui/button/action'); var tabs = require("sdk/tabs"); var pagemod = require("sdk/page-mod"); var data = require("sdk/self").data;   var button = buttons.actionbutton({   id: "mozilla-link",   label: "visit mozilla",   icon: {     "16": "./icon-16.png",     "32": "./icon-32.png",     "64": "./icon-64.png"   },   onclick: handleclick });  function handleclick(state) {   //tabs.open("http://www.mozilla.org/");   tabs.open("http://www.amazon.com");  }  pagemod.pagemod({   include: "*",   contentscriptfile: data.url("modify-content.js"),   onattach: function(worker) {     worker.port.emit("getelements", tag);     worker.port.on("gotelement", function(elementcontent) {       console.log(elementcontent);     });   } }); 

this modify-content.js

self.port.on("getelements", function(tag) {    var elements = document.getelementsbytagname(tag);   (var = 0; < elements.length; i++) {      var isbn = elements[i].innertext.match("(isbn[-]*(1[03])*[ ]*(: ){0,1})*(([0-9xx][- ]*){13}|([0-9xx][- ]*){10})");      if(isbn != undefined){         //self.port.emit("gotelement", elements[i].innerhtml);         console.log(isbn);           }      self.port.emit("gotelement", elements[i].innerhtml);   } }); 

the isbn's found. how manipulate dom element surrounding isbn?

if understand question correctly, you're having trouble translating innertext regexp match, string, nearest html element of match.

the difficult part dom tree. if <div> has <p> has <span> has isbn number, of elements' innertext contain isbn number. want reach "deepest" element contains match, ignoring of parents.

one (rather expensive, brute-force) way of doing this, recursively looping through elements, layer layer.

  • when there match in innertext, we'll @ every child element.
  • if none of children has match, return current element because it's last known dom element had match

other performance, think there still edge cases won't match. example, if there's <span> contains three, comma separated, isbn numbers. you'll have add 1 last layer: layer creates new elements around each individual string.

var isbnregexp = new regexp("(isbn[-]*(1[03])*[ ]*(: ){0,1})*(([0-9xx][- ]*){13}|([0-9xx][- ]*){10})");    var start = document.body;    var finddeepestmatch = function(el, regexp, result) {    result = result || [];      if (regexp.test(el.innerhtml)) {      var childmatches = array.from(el.children)        .filter(child => regexp.test(child.innerhtml));        // case 1: there's match here, not in of children: return el      if (childmatches.length === 0) {        result.push(el);      } else {        childmatches.foreach(child => finddeepestmatch(child, regexp, result));      }    }      return result;  };    console.time("find results")  var results = finddeepestmatch(start, isbnregexp);  console.timeend("find results")    var makeisbn = el => {    el.classlist.add("isbn");    el.addeventlistener("click", () => console.log(el.innertext));  };    results.foreach(makeisbn);
.isbn { color: green; border-radius: 3px; background: rgba(0,255,0,0.2); cursor: pointer; }
<div>    <div>      <ul>        <li>          book: <span>978-0451524935</span>        </li>        <li>          nested book: <span><strong>isbn</strong>-978-0451524935</span>        </li>        <li>          phone number: <span>0012-34-5678909</span>  <code><-- regexp problem?</code>        </li>        <li>          email: <span>abc@def.gh</span>        </li>      </ul>    </div>    <div>      here no isbn numbers    </div>    here's 1 <a><strong>isbn</strong>-<em>978</em>-0451524935</a>  </div>


Comments

Popular posts from this blog

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -