From cc15553795b00588a4acebce79475a6598aa23b5 Mon Sep 17 00:00:00 2001 From: Andrew Cantino Date: Sat, 21 Jan 2023 10:59:12 -0800 Subject: [PATCH] Fix guard pattern issue --- Guardfile | 6 +- build/js/core-spec.js | 40 ++ build/js/{core => }/core.js | 9 +- build/js/dom-spec.js | 269 ++++++++++++ build/js/{core => }/dom.js | 152 +++---- build/js/jquery-include.js | 1 - build/js/spec-helper.js | 22 + build/js/wizard-spec.js | 90 ++++ build/selectorgadget_combined.js | 162 +++---- build/selectorgadget_combined.min.js | 8 +- spec/compiled/core-spec.js | 1 - spec/compiled/core.js | 627 +++++++++++++++++++++++++++ spec/compiled/dom-spec.js | 24 +- spec/compiled/dom.js | 553 +++++++++++++++++++++++ spec/compiled/jquery-include.js | 4 + spec/compiled/spec-helper.js | 9 +- spec/compiled/wizard-spec.js | 5 +- 17 files changed, 1794 insertions(+), 188 deletions(-) create mode 100644 build/js/core-spec.js rename build/js/{core => }/core.js (99%) create mode 100644 build/js/dom-spec.js rename build/js/{core => }/dom.js (79%) create mode 100644 build/js/spec-helper.js create mode 100644 build/js/wizard-spec.js create mode 100644 spec/compiled/core.js create mode 100644 spec/compiled/dom.js create mode 100644 spec/compiled/jquery-include.js diff --git a/Guardfile b/Guardfile index e457017..1977c3c 100644 --- a/Guardfile +++ b/Guardfile @@ -6,20 +6,20 @@ require 'yui/compressor' require 'fileutils' # Specs -guard 'coffeescript', :input => 'spec', :output => 'spec/compiled', :all_on_start => true +guard 'coffeescript', :input => 'spec', :output => 'spec/compiled', :patterns => [%r{^.+\.(?:coffee|coffee\.md|litcoffee)$}], :all_on_start => true # Core Code FileUtils.mkdir_p File.join(File.dirname(__FILE__), 'build', 'js') FileUtils.mkdir_p File.join(File.dirname(__FILE__), 'build', 'css') -guard 'coffeescript', :input => 'lib/js', :output => 'build/js', :all_on_start => true +guard 'coffeescript', :input => 'lib/js', :output => 'build/js', :patterns => [%r{^.+\.(?:coffee|coffee\.md|litcoffee)$}], :all_on_start => true guard 'sass', :input => 'lib/css', :output => 'build/css', :all_on_start => true, :line_numbers => true guard 'concat', :all_on_start => true, :type => "js", - :files => %w(vendor/jquery build/js/jquery-include vendor/diff/diff_match_patch build/js/core/dom build/js/core/core), + :files => %w(vendor/jquery build/js/jquery-include vendor/diff/diff_match_patch build/js/dom build/js/core), :input_dir => ".", :output => "build/selectorgadget_combined" diff --git a/build/js/core-spec.js b/build/js/core-spec.js new file mode 100644 index 0000000..7669260 --- /dev/null +++ b/build/js/core-spec.js @@ -0,0 +1,40 @@ +(function() { + describe("SelectorGadget", function() { + var sg; + sg = null; + beforeEach(function() { + return sg = new SelectorGadget(); + }); + return describe("composeRemoteUrl", function() { + it("works with no existing query", function() { + expect(sg.composeRemoteUrl("http://www.blah.com").split("?")[0]).toEqual("http://www.blah.com"); + expect(sg.composeRemoteUrl("http://www.blah.com").split("?")[1].split("&")[0].split("=")[0]).toEqual("t"); + expect(sg.composeRemoteUrl("http://www.blah.com").split("?")[1].split("&")[1].split("=")[0]).toEqual("url"); + expect(sg.composeRemoteUrl("http://www.blah.com", { + blah: "hi" + }).split("?")[1].split("&")[2].split("=")[0]).toEqual("blah"); + return expect(sg.composeRemoteUrl("http://www.blah.com", { + blah: "hi" + }).split("?")[1].split("&")[2].split("=")[1]).toEqual("hi"); + }); + return it("works with an existing query", function() { + var url; + url = "http://www.blah.com?a=b&c=d"; + expect(sg.composeRemoteUrl(url).split("?")[0]).toEqual("http://www.blah.com"); + expect(sg.composeRemoteUrl(url).split("?")[1].split("&")[0].split("=")[0]).toEqual("a"); + expect(sg.composeRemoteUrl(url).split("?")[1].split("&")[0].split("=")[1]).toEqual("b"); + expect(sg.composeRemoteUrl(url).split("?")[1].split("&")[1].split("=")[0]).toEqual("c"); + expect(sg.composeRemoteUrl(url).split("?")[1].split("&")[1].split("=")[1]).toEqual("d"); + expect(sg.composeRemoteUrl(url).split("?")[1].split("&")[2].split("=")[0]).toEqual("t"); + expect(sg.composeRemoteUrl(url).split("?")[1].split("&")[3].split("=")[0]).toEqual("url"); + expect(sg.composeRemoteUrl(url, { + blah: "hi" + }).split("?")[1].split("&")[4].split("=")[0]).toEqual("blah"); + return expect(sg.composeRemoteUrl(url, { + blah: "hi" + }).split("?")[1].split("&")[4].split("=")[1]).toEqual("hi"); + }); + }); + }); + +}).call(this); diff --git a/build/js/core/core.js b/build/js/core.js similarity index 99% rename from build/js/core/core.js rename to build/js/core.js index a9505a7..bf557c5 100644 --- a/build/js/core/core.js +++ b/build/js/core.js @@ -22,14 +22,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - + */ (function() { var SelectorGadget; window.SelectorGadget = SelectorGadget = (function() { - function SelectorGadget() {} SelectorGadget.prototype.border_width = 5; @@ -225,7 +223,7 @@ }; SelectorGadget.prototype.highlightIframe = function(elem, click) { - var block, instructions, p, self, src, target; + var block, e, instructions, p, self, src, target; p = elem.offset(); self = this; target = jQuerySG(click.target); @@ -246,7 +244,8 @@ src = null; try { src = elem.contents().get(0).location.href; - } catch (e) { + } catch (error) { + e = error; src = elem.attr("src"); } instructions.append(jQuerySG("click here to open it").attr("href", src)); diff --git a/build/js/dom-spec.js b/build/js/dom-spec.js new file mode 100644 index 0000000..8acc252 --- /dev/null +++ b/build/js/dom-spec.js @@ -0,0 +1,269 @@ +(function() { + var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + describe("DomPredictionHelper", function() { + var dom, fixtures; + fixtures = { + class_name_tests: '
' + '
' + ' Hello ' + '
' + '
', + leaves: "
" + "" + "  " + "" + "" + "  " + "" + "" + "  " + "" + " " + "
", + big_structure: "
" + " " + " " + " " + " " + " " + "
" + "
hi
" + "
" + " " + "
" + "
" + "
" + "
" + "
" + "
" + "
" + "" + "" + " " + " " + " " + "
" + "
" + " " + "
" + "
" + "" + "
" + " " + " " + "
" + " Yo" + "
" + "
" + "
" + "
" + "" + "" + "" + "
" + "
" + "

Awesome

" + " Goal" + "
" + "
" + "

Awesome

" + " Goal" + "
" + "
" + "

Awesome

" + " Not Goal" + "
" + "
" + "" + "Department:IT&C MANAGEMENT SERVICES

" + "Requisition ID:20913

" + "Job Title:Manager, Strategic Systems
" + "Location:El Segundo, CA (Los Angeles)

" + }; + dom = null; + beforeEach(function() { + return dom = new DomPredictionHelper(); + }); + describe("escapeCssNames", function() { + return it("escapes illegal characters in css", function() { + expect(dom.escapeCssNames("this.is.a.test")).toEqual("this\\.is\\.a\\.test"); + expect(dom.escapeCssNames("this#is#a#test")).toEqual("this\\#is\\#a\\#test"); + expect(dom.escapeCssNames("this>is>a>test")).toEqual("this\\>is\\>a\\>test"); + expect(dom.escapeCssNames("this,is,a,test")).toEqual("this\\,is\\,a\\,test"); + expect(dom.escapeCssNames("this,is,a|test")).toEqual("this\\,is\\,a\\|test"); + expect(dom.escapeCssNames("selectorgadget_blahblah")).toEqual(""); + expect(dom.escapeCssNames("selectorgadget_suggested")).toEqual(""); + expect(dom.escapeCssNames("suggested ")).toEqual("suggested"); + expect(dom.escapeCssNames("hello\\")).toEqual("hello\\\\"); + return expect(dom.escapeCssNames("iCIMS_InfoMsg_Job")).toEqual("iCIMS_InfoMsg_Job"); + }); + }); + describe("tokenizeCss", function() { + return it("breaks css selectors into tokens", function() { + expect(dom.tokenizeCss("div#id")).toEqual(["div", "#id"]); + expect(dom.tokenizeCss("div#id").toString()).not.toEqual(["div#", "id"]); + expect(dom.tokenizeCss("div#id").toString()).not.toEqual(["div", "id"]); + expect(dom.tokenizeCss("div,html").toString()).not.toEqual(["div", " ", ",", " ", "id"]); + expect(dom.tokenizeCss("div #id")).toEqual(["div", " ", "#id"]); + expect(dom.tokenizeCss("div \t#id")).toEqual(["div", " ", "#id"]); + expect(dom.tokenizeCss("div div#id.class1.class2:nth-child(2) span")).toEqual(["div", " ", "div", "#id", ".class1", ".class2", ":nth-child(2)", " ", "span"]); + expect(dom.tokenizeCss("div > id")).toEqual(["div", " ", ">", " ", "id"]); + expect(dom.tokenizeCss("div>id")).toEqual(["div", " ", ">", " ", "id"]); + expect(dom.tokenizeCss("div.class div a#blah\\.hi")).toEqual(["div", ".class", " ", "div", " ", "a", "#blah\\.hi"]); + return expect(dom.tokenizeCss("strong~ h1:nth-child(2)+ b")).toEqual(["strong", "~", " ", "h1", ":nth-child(2)", "+", " ", "b"]); + }); + }); + describe("tokenizeCssForDiff", function() { + return it("should tokenize css for diffing", function() { + expect(dom.tokenizeCssForDiff("div > id")).toEqual(["div", " ", ">", " ", "id"]); + expect(dom.tokenizeCssForDiff("div.class>id")).toEqual(["div", ".class", " ", ">", " ", "id"]); + return expect(dom.tokenizeCssForDiff("strong#hi~ h1:nth-child(2)+ b")).toEqual(["strong#hi~", " ", "h1:nth-child(2)+", " ", "b"]); + }); + }); + describe("encodeCssForDiff", function() { + it("should encode the css in preparation for diffing", function() { + var existing_tokens, new_strings, strings; + existing_tokens = {}; + strings = ["body div#main #something", "body div#main #something_else"]; + new_strings = dom.encodeCssForDiff(strings, existing_tokens); + expect(new_strings[1].substring(0, 1)).toEqual(new_strings[0].substring(0, 1)); + expect(dom.invertObject(existing_tokens)[new_strings[0].substring(0, 1)]).toEqual('body'); + expect(new_strings[0].substring(1, 2)).toEqual(new_strings[1].substring(1, 2)); + expect(dom.invertObject(existing_tokens)[new_strings[0].substring(1, 2)]).toEqual(' '); + expect(new_strings[0].substring(2, 3)).toEqual(new_strings[1].substring(2, 3)); + expect(new_strings[0].substring(3, 4)).toEqual(new_strings[1].substring(3, 4)); + expect(dom.invertObject(existing_tokens)[new_strings[0].substring(3, 4)]).toEqual('#main'); + return expect(new_strings[0].substring(5, 6)).not.toEqual(new_strings[1].substring(5, 6)); + }); + return it("should encode and decode to the same values", function() { + var existing_tokens, new_strings, strings; + existing_tokens = {}; + strings = ["body div#main #something", "body div#main #something_else"]; + new_strings = dom.encodeCssForDiff(strings, existing_tokens); + return expect(dom.decodeCss(new_strings[0], existing_tokens)).toEqual("body div#main #something"); + }); + }); + describe("cleanCss", function() { + return it("should clean unneeded white space and child and sibling selectors", function() { + expect(dom.cleanCss("tr>td#hi")).toEqual("tr > td#hi"); + expect(dom.cleanCss("tr > td#hi")).toEqual("tr > td#hi"); + expect(dom.cleanCss(", , > tr > > > td#hi >")).toEqual("tr > td#hi"); + expect(dom.cleanCss("h1~ hello+ br")).toEqual("h1~ hello+ br"); + expect(dom.cleanCss(" ~ hello+ br")).toEqual("hello+ br"); + expect(dom.cleanCss(" + ~ ")).toEqual(""); + return expect(dom.cleanCss("br+")).toEqual("br"); + }); + }); + describe("cssDiff", function() { + beforeEach(function() { + return jQuerySG("#jasmine-content").html(fixtures.leaves); + }); + return it("can diff two css selectors", function() { + var p1, p2; + expect(dom.cssDiff([])).toEqual(''); + expect(dom.cssDiff([''])).toEqual(''); + expect(dom.cssDiff(["body div#main #something", "body div#main #something_else"])).toEqual('body div#main'); + expect(dom.cssDiff(["body blah div#main", "body div#main"])).toEqual('body div#main'); + expect(dom.cssDiff(["body blah a div#main", "body div#main"])).toEqual('body div#main'); + p1 = dom.pathOf(jQuerySG('#parent1 span.sibling:nth-child(1)').get(0)); + p2 = dom.pathOf(jQuerySG('#parent1 span.sibling:nth-child(2)').get(0)); + expect(dom.cssDiff([p1, p2])).toEqual('body > div#jasmine-content:nth-child(2) > div#parent1:nth-child(1) > span.sibling'); + expect(dom.cssDiff(["ul li#foo", "li div#foo"])).toEqual('li#foo'); + return expect(dom.cssDiff(["ul > li#foo", "ul > li > ol > li#foo"])).toEqual('ul > li#foo'); + }); + }); + describe("childElemNumber", function() { + return it("returns the element number of the child", function() { + var parent; + parent = jQuerySG('
').append(jQuerySG('hello')).append(jQuerySG('hi')).append(document.createTextNode('hi')).append(jQuerySG('there')).get(0); + expect(dom.childElemNumber(parent.childNodes[0])).toEqual(0); + expect(dom.childElemNumber(parent.childNodes[1])).toEqual(1); + expect(dom.childElemNumber(parent.childNodes[2])).toEqual(2); + expect(dom.childElemNumber(jQuerySG(':nth-child(1)', parent).get(0))).toEqual(0); + expect(dom.childElemNumber(jQuerySG(':nth-child(2)', parent).get(0))).toEqual(1); + return expect(dom.childElemNumber(jQuerySG(':nth-child(3)', parent).get(0))).toEqual(2); + }); + }); + describe("pathOf", function() { + beforeEach(function() { + return jQuerySG("#jasmine-content").append(fixtures.class_name_tests).append(fixtures.leaves); + }); + it("returns the full dom path of an element", function() { + expect(dom.pathOf(jQuerySG('#leaf1').get(0)).indexOf("#leaf1")).toBeGreaterThan(-1); + expect(dom.pathOf(jQuerySG('#leaf1').get(0)).indexOf("span.sibling.something.else:nth-child(2) > i#leaf1")).toBeGreaterThan(-1); + expect(dom.pathOf(jQuerySG('#class_name_tests #moo').get(0)).indexOf(".iCIMS_InfoMsg.iCIMS_InfoMsg_Job")).toBeGreaterThan(-1); + return expect(dom.pathOf(jQuerySG('#class_name_tests #moo').get(0)).indexOf("body:nth-child")).toEqual(-1); + }); + return it("should add siblings with pluses and tildes", function() { + return expect(dom.pathOf(jQuerySG('#parent1 .sibling.something.else').get(0)).indexOf("span#some_id.sibling:nth-child(1)+ span.sibling.something.else:nth-child(2)")).toBeGreaterThan(-1); + }); + }); + describe("simplifyCss", function() { + beforeEach(function() { + return jQuerySG("#jasmine-content").append(fixtures.big_structure); + }); + it("should simplify css based on selected and rejected sets", function() { + expect(dom.simplifyCss("body", jQuerySG("body"), jQuerySG([]))).toEqual("body"); + expect(dom.simplifyCss("body", jQuerySG("a"), jQuerySG([]))).toEqual(""); + expect(dom.simplifyCss("body", jQuerySG([]), jQuerySG([]))).toEqual(""); + expect(dom.simplifyCss("tr td", jQuerySG("tr td div, tr td"), jQuerySG([]))).toEqual(""); + expect(dom.simplifyCss("tr td", jQuerySG("table tr td, tr td"), jQuerySG([]))).toEqual("td"); + expect(dom.simplifyCss("strong > div", jQuerySG("div b strong div"), jQuerySG("div strong div#a b div"))).toEqual("strong > div"); + expect(dom.simplifyCss("tr td", jQuerySG("table tr td, tr td"), jQuerySG("tr"))).toEqual("td"); + expect(dom.simplifyCss("#jobs > li:nth-child(3)", jQuerySG('#jobs>li:nth-child(3)'), jQuerySG('#jobs ul li:nth-child(3)'))).toEqual("#jobs > li"); + return expect(dom.simplifyCss("div+ ul#jobs > li:nth-child(3)", jQuerySG('#jobs>li:nth-child(3)'), jQuerySG('#jobs ul li:nth-child(3)'))).toEqual("#jobs > li"); + }); + return it("should work with numerical ids", function() { + return expect(dom.simplifyCss("table.reasonable>tr>td#omg-im-ugly-7777777", jQuerySG('#omg-im-ugly-7777777'), jQuerySG('#something_else td'))).toEqual(".reasonable td"); + }); + }); + describe("positionOfSpaceBeforeIndexOrLineStart", function() { + return it("should return the position of the space before index or line start", function() { + expect(dom.positionOfSpaceBeforeIndexOrLineStart(3, ["a", "b", "c", "d"])).toEqual(0); + expect(dom.positionOfSpaceBeforeIndexOrLineStart(3, ["a", " ", "c", "d"])).toEqual(1); + return expect(dom.positionOfSpaceBeforeIndexOrLineStart(3, ["a", " ", " ", "d", "e"])).toEqual(2); + }); + }); + describe("predictCss", function() { + beforeEach(function() { + return jQuerySG("#jasmine-content").append(fixtures.leaves).append(fixtures.big_structure); + }); + return it("predicts css", function() { + expect(dom.predictCss(jQuerySG('#parent1 span.sibling:nth-child(1), #parent1 span.sibling:nth-child(2)'), jQuerySG("dfdfdf"))).toEqual('.sibling'); + expect(jQuerySG('#jobs>li:nth-child(3)').length).toEqual(1); + expect(jQuerySG('#jobs ul li:nth-child(3)').length).toEqual(1); + expect(dom.predictCss(jQuerySG('#jobs>li:nth-child(3)'), jQuerySG('#jobs ul li:nth-child(3)'))).toEqual('#jobs > li'); + expect('#leaf1', dom.predictCss(jQuerySG('#parent1 i'), jQuerySG('#parent1 b'))).toEqual('#leaf1'); + expect(dom.predictCss(jQuerySG('#sibling_test h3 + span'), jQuerySG('#sibling_test h4 + span'))).toEqual('.a+ span'); + return expect(dom.predictCss(jQuerySG('#sibling_test h3.a + span'), jQuerySG('#sibling_test h4 + span'))).toEqual('.a+ span'); + }); + }); + describe("selectorGets", function() { + beforeEach(function() { + return jQuerySG("#jasmine-content").append(fixtures.leaves).append(fixtures.big_structure); + }); + return it("determines how the selector matches the set", function() { + expect(jQuerySG('table td div#a, #something_else td div.hi').length).toEqual(2); + expect(dom.selectorGets('all', jQuerySG('table td div#a, #something_else td div#a'), 'div#a')).toEqual(true); + expect(jQuerySG('table td div:nth-child(2), #something_else td div.hi').length).toEqual(2); + expect(dom.selectorGets('all', jQuerySG('table td div#a.hi:nth-child(2), #something_else td div#a.hi'), 'div#a')).toEqual(true); + expect(dom.selectorGets('all', jQuerySG("generates-empty-dflkjsdf"), '#b')).toEqual(false); + expect(dom.selectorGets('none', jQuerySG("generates-empty-dflkjsdf"), '#b')).toEqual(true); + expect(dom.selectorGets('none', jQuerySG('table td div#a, #something_else td div#a'), '#b')).toEqual(true); + expect(dom.selectorGets('none', jQuerySG('table td div#a, #something_else td div#a'), 'table')).toEqual(true); + return expect(dom.selectorGets('none', jQuerySG('table, #something_else td div#a'), 'table')).toEqual(false); + }); + }); + describe("wouldLeaveFreeFloatingNthChild", function() { + return it("determines if a floating nthchild would be left by the removal of the specified element", function() { + expect(dom.wouldLeaveFreeFloatingNthChild(["a", ":nth-child(0)", " ", "div"], 0)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["a", ":nth-child(0)", " ", "div"], 1)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["a", ":nth-child(0)", " ", "div"], 2)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["a", ":nth-child(0)", " ", "div"], 3)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)", " ", "div"], 0)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)", " ", "div"], 1)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)", " ", "div"], 2)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)", " ", "div"], 3)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)", " ", "div"], 4)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)", " ", "div"], 5)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)"], 3)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ".hi", " ", "a", ":nth-child(0)"], 4)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", ":nth-child(0)"], 0)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild([" ", "div", ":nth-child(0)"], 1)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild([".a", ":nth-child(0)"], 0)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild([" ", "#a", ":nth-child(0)"], 1)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["div", " ", "#a", ":nth-child(0)"], 2)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild([":nth-child(2)", " ", ":nth-child(2)", " ", ":nth-child(2)", " ", ":nth-child(1)", " ", ":nth-child(1)", " ", "#today", ":nth-child(1)", " ", "#todaybd", ":nth-child(3)"], 10)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["a", ":nth-child(0)"], 0)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["a", "", "", ":nth-child(0)"], 0)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["", "", "a", "", "", ":nth-child(0)"], 2)).toBeTruthy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["a", ":nth-child(0)"], 1)).toBeFalsy(); + expect(dom.wouldLeaveFreeFloatingNthChild(["a"], 0)).toBeFalsy(); + return expect(dom.wouldLeaveFreeFloatingNthChild([":nth-child(0)"], 0)).toBeFalsy(); + }); + }); + describe("_removeElements", function() { + return it("removes matching elements", function() { + expect(dom._removeElements(0, ["a", "b", "c"], "a", function() { + return true; + })).toEqual(["", "b", "c"]); + expect(dom._removeElements(0, ["a", "b", "c"], "a", function() { + return false; + })).toEqual(["a", "b", "c"]); + expect(dom._removeElements(4, ["a", " ", "c", "d", "+", " ", "e"], "+", function() { + return true; + })).toEqual(["a", "", "", "", "", " ", "e"]); + expect(dom._removeElements(4, ["a", " ", "c", "d", "+", " ", "e"], "+", function() { + return false; + })).toEqual(["a", " ", "c", "d", "+", " ", "e"]); + expect(dom._removeElements(4, ["a", "e", "c", "d", "+", " ", "e"], "+", function() { + return true; + })).toEqual(["", "", "", "", "", " ", "e"]); + return expect(dom._removeElements(4, ["a", "e", "c", "d", "+", " ", "e"], "+", function() { + return false; + })).toEqual(["a", "e", "c", "d", "+", " ", "e"]); + }); + }); + return describe("cssToXPath", function() { + beforeEach(function() { + var fixture_contents, fixture_name, results; + results = []; + for (fixture_name in fixtures) { + fixture_contents = fixtures[fixture_name]; + results.push(jQuerySG("#jasmine-content").append(fixture_contents)); + } + return results; + }); + return it("converts css to xpath", function() { + var css, cssAndXPathMatch, expressions, i, len, results; + cssAndXPathMatch = function(css, xpath) { + var css_matches, elem, elems; + css_matches = jQuerySG(css); + elems = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null); + while (elem = elems.iterateNext()) { + if (indexOf.call(css_matches, elem) < 0) { + return false; + } + } + return true; + }; + expressions = ['a', '#leaf1', 'body #leaf1', 'span.sibling.something.else', 'a , b , #leaf1', 'span.sibling', '.else.something', ':nth-child(2) i#leaf1', 'span.something.else:nth-child(2) i#leaf1']; + results = []; + for (i = 0, len = expressions.length; i < len; i++) { + css = expressions[i]; + results.push(expect(cssAndXPathMatch(css, dom.cssToXPath(css))).toBeTruthy()); + } + return results; + }); + }); + }); + +}).call(this); diff --git a/build/js/core/dom.js b/build/js/dom.js similarity index 79% rename from build/js/core/dom.js rename to build/js/dom.js index 20fde85..18394db 100644 --- a/build/js/core/dom.js +++ b/build/js/dom.js @@ -22,14 +22,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - + */ (function() { var DomPredictionHelper; window.DomPredictionHelper = DomPredictionHelper = (function() { - function DomPredictionHelper() {} DomPredictionHelper.prototype.recursiveNodes = function(e) { @@ -44,12 +42,14 @@ }; DomPredictionHelper.prototype.escapeCssNames = function(name) { + var e; if (name) { try { return name.replace(/\bselectorgadget_\w+\b/g, '').replace(/\\/g, '\\\\').replace(/[\#\;\&\,\.\+\*\~\'\:\"\!\^\$\[\]\(\)\=\>\|\/]/g, function(e) { return '\\' + e; }).replace(/\s+/, ''); - } catch (e) { + } catch (error) { + e = error; if (window.console) { console.log('---'); console.log("exception in escapeCssNames"); @@ -75,11 +75,11 @@ }; DomPredictionHelper.prototype.siblingsWithoutTextNodes = function(e) { - var filtered_nodes, node, nodes, _i, _len; + var filtered_nodes, k, len, node, nodes; nodes = e.parentNode.childNodes; filtered_nodes = []; - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - node = nodes[_i]; + for (k = 0, len = nodes.length; k < len; k++) { + node = nodes[k]; if (node.nodeName.substring(0, 1) === "#") { continue; } @@ -92,11 +92,11 @@ }; DomPredictionHelper.prototype.pathOf = function(elem) { - var e, j, path, siblings, _i, _len, _ref; + var e, j, k, len, path, ref, siblings; path = ""; - _ref = this.recursiveNodes(elem); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - e = _ref[_i]; + ref = this.recursiveNodes(elem); + for (k = 0, len = ref.length; k < len; k++) { + e = ref[k]; if (e) { siblings = this.siblingsWithoutTextNodes(e); if (e.nodeName.toLowerCase() !== "body") { @@ -118,16 +118,16 @@ }; DomPredictionHelper.prototype.cssDescriptor = function(node) { - var cssName, escaped, path, _i, _len, _ref; + var cssName, escaped, k, len, path, ref; path = node.nodeName.toLowerCase(); escaped = node.id && this.escapeCssNames(new String(node.id)); if (escaped && escaped.length > 0) { path += '#' + escaped; } if (node.className) { - _ref = node.className.split(" "); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - cssName = _ref[_i]; + ref = node.className.split(" "); + for (k = 0, len = ref.length; k < len; k++) { + cssName = ref[k]; escaped = this.escapeCssNames(cssName); if (cssName && escaped.length > 0) { path += '.' + escaped; @@ -141,10 +141,11 @@ }; DomPredictionHelper.prototype.cssDiff = function(array) { - var collective_common, cssElem, diff, dmp, encoded_css_array, existing_tokens, part, _i, _j, _len, _len1; + var collective_common, cssElem, diff, dmp, e, encoded_css_array, existing_tokens, k, l, len, len1, part; try { dmp = new diff_match_patch(); - } catch (e) { + } catch (error) { + e = error; throw "Please include the diff_match_patch library."; } if (typeof array === 'undefined' || array.length === 0) { @@ -153,12 +154,12 @@ existing_tokens = {}; encoded_css_array = this.encodeCssForDiff(array, existing_tokens); collective_common = encoded_css_array.pop(); - for (_i = 0, _len = encoded_css_array.length; _i < _len; _i++) { - cssElem = encoded_css_array[_i]; + for (k = 0, len = encoded_css_array.length; k < len; k++) { + cssElem = encoded_css_array[k]; diff = dmp.diff_main(collective_common, cssElem); collective_common = ''; - for (_j = 0, _len1 = diff.length; _j < _len1; _j++) { - part = diff[_j]; + for (l = 0, len1 = diff.length; l < len1; l++) { + part = diff[l]; if (part[0] === 0) { collective_common += part[1]; } @@ -168,13 +169,13 @@ }; DomPredictionHelper.prototype.tokenizeCss = function(css_string) { - var char, skip, tokens, word, _i, _len, _ref; + var char, k, len, ref, skip, tokens, word; skip = false; word = ''; tokens = []; - _ref = this.cleanCss(css_string); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - char = _ref[_i]; + ref = this.cleanCss(css_string); + for (k = 0, len = ref.length; k < len; k++) { + char = ref[k]; if (skip) { skip = false; } else if (char === '\\') { @@ -198,12 +199,12 @@ }; DomPredictionHelper.prototype.tokenizeCssForDiff = function(css_string) { - var block, combined_tokens, token, _i, _len, _ref; + var block, combined_tokens, k, len, ref, token; combined_tokens = []; block = []; - _ref = this.tokenizeCss(css_string); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - token = _ref[_i]; + ref = this.tokenizeCss(css_string); + for (k = 0, len = ref.length; k < len; k++) { + token = ref[k]; block.push(token); if (token === ' ' && block.length > 0) { combined_tokens = combined_tokens.concat(block); @@ -220,27 +221,27 @@ }; DomPredictionHelper.prototype.decodeCss = function(string, existing_tokens) { - var character, inverted, out, _i, _len, _ref; + var character, inverted, k, len, out, ref; inverted = this.invertObject(existing_tokens); out = ''; - _ref = string.split(''); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - character = _ref[_i]; + ref = string.split(''); + for (k = 0, len = ref.length; k < len; k++) { + character = ref[k]; out += inverted[character]; } return this.cleanCss(out); }; DomPredictionHelper.prototype.encodeCssForDiff = function(strings, existing_tokens) { - var codepoint, out, string, strings_out, token, _i, _j, _len, _len1, _ref; + var codepoint, k, l, len, len1, out, ref, string, strings_out, token; codepoint = 50; strings_out = []; - for (_i = 0, _len = strings.length; _i < _len; _i++) { - string = strings[_i]; + for (k = 0, len = strings.length; k < len; k++) { + string = strings[k]; out = new String(); - _ref = this.tokenizeCssForDiff(string); - for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { - token = _ref[_j]; + ref = this.tokenizeCssForDiff(string); + for (l = 0, len1 = ref.length; l < len1; l++) { + token = ref[l]; if (!existing_tokens[token]) { existing_tokens[token] = String.fromCharCode(codepoint++); } @@ -252,12 +253,12 @@ }; DomPredictionHelper.prototype.tokenPriorities = function(tokens) { - var epsilon, first, i, priorities, second, token, _i, _len; + var epsilon, first, i, k, len, priorities, second, token; epsilon = 0.001; priorities = new Array(); i = 0; - for (_i = 0, _len = tokens.length; _i < _len; _i++) { - token = tokens[_i]; + for (k = 0, len = tokens.length; k < len; k++) { + token = tokens[k]; first = token.substring(0, 1); second = token.substring(1, 2); if (first === ':' && second === 'n') { @@ -285,10 +286,10 @@ }; DomPredictionHelper.prototype.orderFromPriorities = function(priorities) { - var i, ordering, tmp, _i, _j, _ref, _ref1; + var i, k, l, ordering, ref, ref1, tmp; tmp = new Array(); ordering = new Array(); - for (i = _i = 0, _ref = priorities.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + for (i = k = 0, ref = priorities.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { tmp[i] = { value: priorities[i], original: i @@ -297,15 +298,14 @@ tmp.sort(function(a, b) { return a.value - b.value; }); - for (i = _j = 0, _ref1 = priorities.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) { + for (i = l = 0, ref1 = priorities.length; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) { ordering[i] = tmp[i].original; } return ordering; }; DomPredictionHelper.prototype.simplifyCss = function(css, selected, rejected) { - var best_so_far, first, got_shorter, i, look_back_index, ordering, part, parts, priorities, second, selector, _i, _ref, - _this = this; + var best_so_far, first, got_shorter, i, k, look_back_index, ordering, part, parts, priorities, ref, second, selector; parts = this.tokenizeCss(css); priorities = this.tokenPriorities(parts); ordering = this.orderFromPriorities(priorities); @@ -318,7 +318,7 @@ got_shorter = true; while (got_shorter) { got_shorter = false; - for (i = _i = 0, _ref = parts.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + for (i = k = 0, ref = parts.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { part = ordering[i]; if (parts[part].length === 0) { continue; @@ -331,34 +331,36 @@ if (this.wouldLeaveFreeFloatingNthChild(parts, part)) { continue; } - this._removeElements(part, parts, first, function(selector) { - if (_this.selectorGets('all', selected, selector) && _this.selectorGets('none', rejected, selector) && (selector.length < best_so_far.length || best_so_far.length === 0)) { - best_so_far = selector; - got_shorter = true; - return true; - } else { - return false; - } - }); + this._removeElements(part, parts, first, (function(_this) { + return function(selector) { + if (_this.selectorGets('all', selected, selector) && _this.selectorGets('none', rejected, selector) && (selector.length < best_so_far.length || best_so_far.length === 0)) { + best_so_far = selector; + got_shorter = true; + return true; + } else { + return false; + } + }; + })(this)); } } return this.cleanCss(best_so_far); }; DomPredictionHelper.prototype._removeElements = function(part, parts, firstChar, callback) { - var j, look_back_index, selector, tmp, _i, _j; + var j, k, l, look_back_index, ref, ref1, ref2, ref3, selector, tmp; if (firstChar === '+' || firstChar === '~') { look_back_index = this.positionOfSpaceBeforeIndexOrLineStart(part, parts); } else { look_back_index = part; } tmp = parts.slice(look_back_index, part + 1); - for (j = _i = look_back_index; look_back_index <= part ? _i <= part : _i >= part; j = look_back_index <= part ? ++_i : --_i) { + for (j = k = ref = look_back_index, ref1 = part; ref <= ref1 ? k <= ref1 : k >= ref1; j = ref <= ref1 ? ++k : --k) { parts[j] = ''; } selector = this.cleanCss(parts.join('')); if (selector === '' || !callback(selector)) { - for (j = _j = look_back_index; look_back_index <= part ? _j <= part : _j >= part; j = look_back_index <= part ? ++_j : --_j) { + for (j = l = ref2 = look_back_index, ref3 = part; ref2 <= ref3 ? l <= ref3 : l >= ref3; j = ref2 <= ref3 ? ++l : --l) { parts[j] = tmp[j - look_back_index]; } } @@ -409,10 +411,10 @@ }; DomPredictionHelper.prototype.getPathsFor = function(nodeset) { - var node, out, _i, _len; + var k, len, node, out; out = []; - for (_i = 0, _len = nodeset.length; _i < _len; _i++) { - node = nodeset[_i]; + for (k = 0, len = nodeset.length; k < len; k++) { + node = nodeset[k]; if (node && node.nodeName) { out.push(this.pathOf(node)); } @@ -421,7 +423,7 @@ }; DomPredictionHelper.prototype.predictCss = function(s, r) { - var css, selected, selected_paths, simplest, union, _i, _len; + var css, k, len, selected, selected_paths, simplest, union; if (s.length === 0) { return ''; } @@ -432,8 +434,8 @@ return simplest; } union = ''; - for (_i = 0, _len = s.length; _i < _len; _i++) { - selected = s[_i]; + for (k = 0, len = s.length; k < len; k++) { + selected = s[k]; union = this.pathOf(selected) + ", " + union; } union = this.cleanCss(union); @@ -441,6 +443,7 @@ }; DomPredictionHelper.prototype.selectorGets = function(type, list, the_selector) { + var e; if (list.length === 0 && type === 'all') { return false; } @@ -453,7 +456,8 @@ } else { return !(list.is(the_selector)); } - } catch (e) { + } catch (error) { + e = error; if (window.console) { console.log("Error on selector: " + the_selector); } @@ -472,7 +476,7 @@ }; DomPredictionHelper.prototype.cssToXPath = function(css_string) { - var css_block, out, token, tokens, _i, _len; + var css_block, k, len, out, token, tokens; tokens = this.tokenizeCss(css_string); if (tokens[0] && tokens[0] === ' ') { tokens.splice(0, 1); @@ -482,8 +486,8 @@ } css_block = []; out = ""; - for (_i = 0, _len = tokens.length; _i < _len; _i++) { - token = tokens[_i]; + for (k = 0, len = tokens.length; k < len; k++) { + token = tokens[k]; if (token === ' ') { out += this.cssToXPathBlockHelper(css_block); css_block = []; @@ -495,7 +499,7 @@ }; DomPredictionHelper.prototype.cssToXPathBlockHelper = function(css_block) { - var current, expressions, first, i, out, re, rest, _i, _j, _len, _ref; + var current, expressions, first, i, k, l, len, out, re, ref, rest; if (css_block.length === 0) { return '//'; } @@ -509,8 +513,8 @@ } expressions = []; re = null; - for (_i = 0, _len = css_block.length; _i < _len; _i++) { - current = css_block[_i]; + for (k = 0, len = css_block.length; k < len; k++) { + current = css_block[k]; first = current.substring(0, 1); rest = current.substring(1); if (first === ':') { @@ -530,7 +534,7 @@ if (expressions.length > 0) { out += '['; } - for (i = _j = 0, _ref = expressions.length; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) { + for (i = l = 0, ref = expressions.length; 0 <= ref ? l < ref : l > ref; i = 0 <= ref ? ++l : --l) { out += expressions[i]; if (i < expressions.length - 1) { out += ' and '; diff --git a/build/js/jquery-include.js b/build/js/jquery-include.js index 2806eec..e5ba392 100644 --- a/build/js/jquery-include.js +++ b/build/js/jquery-include.js @@ -1,5 +1,4 @@ (function() { - window.jQuerySG = jQuery.noConflict(true); }).call(this); diff --git a/build/js/spec-helper.js b/build/js/spec-helper.js new file mode 100644 index 0000000..2ca5f0c --- /dev/null +++ b/build/js/spec-helper.js @@ -0,0 +1,22 @@ +(function() { + beforeEach(function() { + jQuerySG.fx.off = true; + jQuerySG('#jasmine-content').empty(); + jasmine.Clock.useMock(); + return jQuerySG.ajaxSettings.xhr = function() { + return expect("you to mock all ajax, but your tests actually seem").toContain("an ajax call"); + }; + }); + + afterEach(function() { + var events, prop, results; + jasmine.Clock.reset(); + events = jQuerySG.data(document, "events"); + results = []; + for (prop in events) { + results.push(delete events[prop]); + } + return results; + }); + +}).call(this); diff --git a/build/js/wizard-spec.js b/build/js/wizard-spec.js new file mode 100644 index 0000000..a406c14 --- /dev/null +++ b/build/js/wizard-spec.js @@ -0,0 +1,90 @@ +(function() { + describe("SelectorGadget wizard features", function() { + var otherCard, ref, selectorCard, sg, struct; + ref = [null, null, null, null], sg = ref[0], selectorCard = ref[1], otherCard = ref[2], struct = ref[3]; + beforeEach(function() { + sg = new SelectorGadget(); + selectorCard = { + name: 'hello' + }; + otherCard = { + prompt: 'goodbye' + }; + return struct = { + selectors: { + card1: "hello", + card2: "hello" + }, + cards: [ + { + prompt: "moose", + close: "something" + }, { + name: "card1", + next: "blah" + }, { + prompt: "moose" + }, { + name: "card2" + } + ] + }; + }); + describe("selectWizardCard", function() { + it("should return null when all cards are satisfied", function() { + return expect(sg.selectWizardCard(struct)).toBeFalsy(); + }); + return it("should return the first card that still needs to be filled", function() { + struct.selectors.card2 = null; + expect(sg.selectWizardCard(struct)).toEqual(struct.cards[2]); + struct.selectors = {}; + return expect(sg.selectWizardCard(struct)).toEqual(struct.cards[0]); + }); + }); + describe("isSelectorCard", function() { + return it("should work", function() { + expect(sg.isSelectorCard(selectorCard)).toBeTruthy(); + return expect(sg.isSelectorCard(otherCard)).toBeFalsy(); + }); + }); + describe("cardType", function() { + return it("should return the correct card type", function() { + expect(sg.cardType(selectorCard)).toEqual('selector_card'); + return expect(sg.cardType(otherCard)).toEqual('info_card'); + }); + }); + describe("injectDefaultCardInfoAsNecessary", function() { + it("should work on an info card", function() { + var close_before, prompt_before; + prompt_before = struct.cards[0].prompt; + close_before = struct.cards[0].close; + sg.injectDefaultCardInfoAsNecessary(struct); + expect(sg.cardType(struct.cards[0])).toEqual('info_card'); + expect(sg.wizard_defaults.info_card.here).toEqual(struct.cards[0].here); + expect(struct.cards[0].prompt).toEqual(prompt_before); + return expect(struct.cards[0].close).toEqual(close_before); + }); + return it("should work on a selector card", function() { + var next_before; + next_before = struct.cards[1].next; + sg.injectDefaultCardInfoAsNecessary(struct); + expect(sg.cardType(struct.cards[1])).toEqual('selector_card'); + expect(sg.wizard_defaults.selector_card.prompt).toEqual(struct.cards[1].prompt); + expect(struct.cards[1].next).toEqual(next_before); + return expect(struct.cards[1].close).toBeFalsy(); + }); + }); + return it("should handle skipIfs", function() { + sg.injectDefaultCardInfoAsNecessary(struct); + struct.cards[1].skip_if = function(json) { + return json.selectors.card2; + }; + expect(sg.handleSkipIfs(struct.cards[1], struct)).toEqual(struct.cards[2]); + struct.cards[2].skip_if = function(json) { + return json.selectors.card2; + }; + return expect(sg.handleSkipIfs(struct.cards[1], struct)).toEqual(struct.cards[3]); + }); + }); + +}).call(this); diff --git a/build/selectorgadget_combined.js b/build/selectorgadget_combined.js index 9b6b6bd..8847552 100644 --- a/build/selectorgadget_combined.js +++ b/build/selectorgadget_combined.js @@ -10881,7 +10881,6 @@ return jQuery; } ); (function() { - window.jQuerySG = jQuery.noConflict(true); }).call(this); @@ -10911,14 +10910,12 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - + */ (function() { var DomPredictionHelper; window.DomPredictionHelper = DomPredictionHelper = (function() { - function DomPredictionHelper() {} DomPredictionHelper.prototype.recursiveNodes = function(e) { @@ -10933,12 +10930,14 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.escapeCssNames = function(name) { + var e; if (name) { try { return name.replace(/\bselectorgadget_\w+\b/g, '').replace(/\\/g, '\\\\').replace(/[\#\;\&\,\.\+\*\~\'\:\"\!\^\$\[\]\(\)\=\>\|\/]/g, function(e) { return '\\' + e; }).replace(/\s+/, ''); - } catch (e) { + } catch (error) { + e = error; if (window.console) { console.log('---'); console.log("exception in escapeCssNames"); @@ -10964,11 +10963,11 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.siblingsWithoutTextNodes = function(e) { - var filtered_nodes, node, nodes, _i, _len; + var filtered_nodes, k, len, node, nodes; nodes = e.parentNode.childNodes; filtered_nodes = []; - for (_i = 0, _len = nodes.length; _i < _len; _i++) { - node = nodes[_i]; + for (k = 0, len = nodes.length; k < len; k++) { + node = nodes[k]; if (node.nodeName.substring(0, 1) === "#") { continue; } @@ -10981,11 +10980,11 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.pathOf = function(elem) { - var e, j, path, siblings, _i, _len, _ref; + var e, j, k, len, path, ref, siblings; path = ""; - _ref = this.recursiveNodes(elem); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - e = _ref[_i]; + ref = this.recursiveNodes(elem); + for (k = 0, len = ref.length; k < len; k++) { + e = ref[k]; if (e) { siblings = this.siblingsWithoutTextNodes(e); if (e.nodeName.toLowerCase() !== "body") { @@ -11007,16 +11006,16 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.cssDescriptor = function(node) { - var cssName, escaped, path, _i, _len, _ref; + var cssName, escaped, k, len, path, ref; path = node.nodeName.toLowerCase(); escaped = node.id && this.escapeCssNames(new String(node.id)); if (escaped && escaped.length > 0) { path += '#' + escaped; } if (node.className) { - _ref = node.className.split(" "); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - cssName = _ref[_i]; + ref = node.className.split(" "); + for (k = 0, len = ref.length; k < len; k++) { + cssName = ref[k]; escaped = this.escapeCssNames(cssName); if (cssName && escaped.length > 0) { path += '.' + escaped; @@ -11030,10 +11029,11 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.cssDiff = function(array) { - var collective_common, cssElem, diff, dmp, encoded_css_array, existing_tokens, part, _i, _j, _len, _len1; + var collective_common, cssElem, diff, dmp, e, encoded_css_array, existing_tokens, k, l, len, len1, part; try { dmp = new diff_match_patch(); - } catch (e) { + } catch (error) { + e = error; throw "Please include the diff_match_patch library."; } if (typeof array === 'undefined' || array.length === 0) { @@ -11042,12 +11042,12 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff existing_tokens = {}; encoded_css_array = this.encodeCssForDiff(array, existing_tokens); collective_common = encoded_css_array.pop(); - for (_i = 0, _len = encoded_css_array.length; _i < _len; _i++) { - cssElem = encoded_css_array[_i]; + for (k = 0, len = encoded_css_array.length; k < len; k++) { + cssElem = encoded_css_array[k]; diff = dmp.diff_main(collective_common, cssElem); collective_common = ''; - for (_j = 0, _len1 = diff.length; _j < _len1; _j++) { - part = diff[_j]; + for (l = 0, len1 = diff.length; l < len1; l++) { + part = diff[l]; if (part[0] === 0) { collective_common += part[1]; } @@ -11057,13 +11057,13 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.tokenizeCss = function(css_string) { - var char, skip, tokens, word, _i, _len, _ref; + var char, k, len, ref, skip, tokens, word; skip = false; word = ''; tokens = []; - _ref = this.cleanCss(css_string); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - char = _ref[_i]; + ref = this.cleanCss(css_string); + for (k = 0, len = ref.length; k < len; k++) { + char = ref[k]; if (skip) { skip = false; } else if (char === '\\') { @@ -11087,12 +11087,12 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.tokenizeCssForDiff = function(css_string) { - var block, combined_tokens, token, _i, _len, _ref; + var block, combined_tokens, k, len, ref, token; combined_tokens = []; block = []; - _ref = this.tokenizeCss(css_string); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - token = _ref[_i]; + ref = this.tokenizeCss(css_string); + for (k = 0, len = ref.length; k < len; k++) { + token = ref[k]; block.push(token); if (token === ' ' && block.length > 0) { combined_tokens = combined_tokens.concat(block); @@ -11109,27 +11109,27 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.decodeCss = function(string, existing_tokens) { - var character, inverted, out, _i, _len, _ref; + var character, inverted, k, len, out, ref; inverted = this.invertObject(existing_tokens); out = ''; - _ref = string.split(''); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - character = _ref[_i]; + ref = string.split(''); + for (k = 0, len = ref.length; k < len; k++) { + character = ref[k]; out += inverted[character]; } return this.cleanCss(out); }; DomPredictionHelper.prototype.encodeCssForDiff = function(strings, existing_tokens) { - var codepoint, out, string, strings_out, token, _i, _j, _len, _len1, _ref; + var codepoint, k, l, len, len1, out, ref, string, strings_out, token; codepoint = 50; strings_out = []; - for (_i = 0, _len = strings.length; _i < _len; _i++) { - string = strings[_i]; + for (k = 0, len = strings.length; k < len; k++) { + string = strings[k]; out = new String(); - _ref = this.tokenizeCssForDiff(string); - for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { - token = _ref[_j]; + ref = this.tokenizeCssForDiff(string); + for (l = 0, len1 = ref.length; l < len1; l++) { + token = ref[l]; if (!existing_tokens[token]) { existing_tokens[token] = String.fromCharCode(codepoint++); } @@ -11141,12 +11141,12 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.tokenPriorities = function(tokens) { - var epsilon, first, i, priorities, second, token, _i, _len; + var epsilon, first, i, k, len, priorities, second, token; epsilon = 0.001; priorities = new Array(); i = 0; - for (_i = 0, _len = tokens.length; _i < _len; _i++) { - token = tokens[_i]; + for (k = 0, len = tokens.length; k < len; k++) { + token = tokens[k]; first = token.substring(0, 1); second = token.substring(1, 2); if (first === ':' && second === 'n') { @@ -11174,10 +11174,10 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.orderFromPriorities = function(priorities) { - var i, ordering, tmp, _i, _j, _ref, _ref1; + var i, k, l, ordering, ref, ref1, tmp; tmp = new Array(); ordering = new Array(); - for (i = _i = 0, _ref = priorities.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + for (i = k = 0, ref = priorities.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { tmp[i] = { value: priorities[i], original: i @@ -11186,15 +11186,14 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff tmp.sort(function(a, b) { return a.value - b.value; }); - for (i = _j = 0, _ref1 = priorities.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) { + for (i = l = 0, ref1 = priorities.length; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) { ordering[i] = tmp[i].original; } return ordering; }; DomPredictionHelper.prototype.simplifyCss = function(css, selected, rejected) { - var best_so_far, first, got_shorter, i, look_back_index, ordering, part, parts, priorities, second, selector, _i, _ref, - _this = this; + var best_so_far, first, got_shorter, i, k, look_back_index, ordering, part, parts, priorities, ref, second, selector; parts = this.tokenizeCss(css); priorities = this.tokenPriorities(parts); ordering = this.orderFromPriorities(priorities); @@ -11207,7 +11206,7 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff got_shorter = true; while (got_shorter) { got_shorter = false; - for (i = _i = 0, _ref = parts.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + for (i = k = 0, ref = parts.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { part = ordering[i]; if (parts[part].length === 0) { continue; @@ -11220,34 +11219,36 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff if (this.wouldLeaveFreeFloatingNthChild(parts, part)) { continue; } - this._removeElements(part, parts, first, function(selector) { - if (_this.selectorGets('all', selected, selector) && _this.selectorGets('none', rejected, selector) && (selector.length < best_so_far.length || best_so_far.length === 0)) { - best_so_far = selector; - got_shorter = true; - return true; - } else { - return false; - } - }); + this._removeElements(part, parts, first, (function(_this) { + return function(selector) { + if (_this.selectorGets('all', selected, selector) && _this.selectorGets('none', rejected, selector) && (selector.length < best_so_far.length || best_so_far.length === 0)) { + best_so_far = selector; + got_shorter = true; + return true; + } else { + return false; + } + }; + })(this)); } } return this.cleanCss(best_so_far); }; DomPredictionHelper.prototype._removeElements = function(part, parts, firstChar, callback) { - var j, look_back_index, selector, tmp, _i, _j; + var j, k, l, look_back_index, ref, ref1, ref2, ref3, selector, tmp; if (firstChar === '+' || firstChar === '~') { look_back_index = this.positionOfSpaceBeforeIndexOrLineStart(part, parts); } else { look_back_index = part; } tmp = parts.slice(look_back_index, part + 1); - for (j = _i = look_back_index; look_back_index <= part ? _i <= part : _i >= part; j = look_back_index <= part ? ++_i : --_i) { + for (j = k = ref = look_back_index, ref1 = part; ref <= ref1 ? k <= ref1 : k >= ref1; j = ref <= ref1 ? ++k : --k) { parts[j] = ''; } selector = this.cleanCss(parts.join('')); if (selector === '' || !callback(selector)) { - for (j = _j = look_back_index; look_back_index <= part ? _j <= part : _j >= part; j = look_back_index <= part ? ++_j : --_j) { + for (j = l = ref2 = look_back_index, ref3 = part; ref2 <= ref3 ? l <= ref3 : l >= ref3; j = ref2 <= ref3 ? ++l : --l) { parts[j] = tmp[j - look_back_index]; } } @@ -11298,10 +11299,10 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.getPathsFor = function(nodeset) { - var node, out, _i, _len; + var k, len, node, out; out = []; - for (_i = 0, _len = nodeset.length; _i < _len; _i++) { - node = nodeset[_i]; + for (k = 0, len = nodeset.length; k < len; k++) { + node = nodeset[k]; if (node && node.nodeName) { out.push(this.pathOf(node)); } @@ -11310,7 +11311,7 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.predictCss = function(s, r) { - var css, selected, selected_paths, simplest, union, _i, _len; + var css, k, len, selected, selected_paths, simplest, union; if (s.length === 0) { return ''; } @@ -11321,8 +11322,8 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff return simplest; } union = ''; - for (_i = 0, _len = s.length; _i < _len; _i++) { - selected = s[_i]; + for (k = 0, len = s.length; k < len; k++) { + selected = s[k]; union = this.pathOf(selected) + ", " + union; } union = this.cleanCss(union); @@ -11330,6 +11331,7 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.selectorGets = function(type, list, the_selector) { + var e; if (list.length === 0 && type === 'all') { return false; } @@ -11342,7 +11344,8 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff } else { return !(list.is(the_selector)); } - } catch (e) { + } catch (error) { + e = error; if (window.console) { console.log("Error on selector: " + the_selector); } @@ -11361,7 +11364,7 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.cssToXPath = function(css_string) { - var css_block, out, token, tokens, _i, _len; + var css_block, k, len, out, token, tokens; tokens = this.tokenizeCss(css_string); if (tokens[0] && tokens[0] === ' ') { tokens.splice(0, 1); @@ -11371,8 +11374,8 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff } css_block = []; out = ""; - for (_i = 0, _len = tokens.length; _i < _len; _i++) { - token = tokens[_i]; + for (k = 0, len = tokens.length; k < len; k++) { + token = tokens[k]; if (token === ' ') { out += this.cssToXPathBlockHelper(css_block); css_block = []; @@ -11384,7 +11387,7 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; DomPredictionHelper.prototype.cssToXPathBlockHelper = function(css_block) { - var current, expressions, first, i, out, re, rest, _i, _j, _len, _ref; + var current, expressions, first, i, k, l, len, out, re, ref, rest; if (css_block.length === 0) { return '//'; } @@ -11398,8 +11401,8 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff } expressions = []; re = null; - for (_i = 0, _len = css_block.length; _i < _len; _i++) { - current = css_block[_i]; + for (k = 0, len = css_block.length; k < len; k++) { + current = css_block[k]; first = current.substring(0, 1); rest = current.substring(1); if (first === ':') { @@ -11419,7 +11422,7 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff if (expressions.length > 0) { out += '['; } - for (i = _j = 0, _ref = expressions.length; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) { + for (i = l = 0, ref = expressions.length; 0 <= ref ? l < ref : l > ref; i = 0 <= ref ? ++l : --l) { out += expressions[i]; if (i < expressions.length - 1) { out += ' and '; @@ -11461,14 +11464,12 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - + */ (function() { var SelectorGadget; window.SelectorGadget = SelectorGadget = (function() { - function SelectorGadget() {} SelectorGadget.prototype.border_width = 5; @@ -11664,7 +11665,7 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff }; SelectorGadget.prototype.highlightIframe = function(elem, click) { - var block, instructions, p, self, src, target; + var block, e, instructions, p, self, src, target; p = elem.offset(); self = this; target = jQuerySG(click.target); @@ -11685,7 +11686,8 @@ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff src = null; try { src = elem.contents().get(0).location.href; - } catch (e) { + } catch (error) { + e = error; src = elem.attr("src"); } instructions.append(jQuerySG("click here to open it").attr("href", src)); diff --git a/build/selectorgadget_combined.min.js b/build/selectorgadget_combined.min.js index 9e40271..a05adf3 100644 --- a/build/selectorgadget_combined.min.js +++ b/build/selectorgadget_combined.min.js @@ -48,8 +48,8 @@ return new C.XMLHttpRequest}catch(e){}};var Jt={0:200,1223:204},Zt=Ce.ajaxSettin LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -function(){window.DomPredictionHelper=function(){function e(){}return e.prototype.recursiveNodes=function(e){var t;return(t=e.nodeName&&e.parentNode&&e!==document.body?this.recursiveNodes(e.parentNode):new Array).push(e),t},e.prototype.escapeCssNames=function(e){if(!e)return"";try{return e.replace(/\bselectorgadget_\w+\b/g,"").replace(/\\/g,"\\\\").replace(/[\#\;\&\,\.\+\*\~\'\:\"\!\^\$\[\]\(\)\=\>\|\/]/g,function(e){return"\\"+e}).replace(/\s+/,"")}catch(t){return window.console&&(console.log("---"),console.log("exception in escapeCssNames"),console.log(e),console.log("---")),""}},e.prototype.childElemNumber=function(e){var t;for(t=0;e.previousSibling&&(e=e.previousSibling);)1===e.nodeType&&t++;return t},e.prototype.siblingsWithoutTextNodes=function(e){var t,n,r,i,o;for(t=[],i=0,o=(r=e.parentNode.childNodes).length;i "}return this.cleanCss(r)},e.prototype.cssDescriptor=function(e){var t,n,r,i,o,s;if(r=e.nodeName.toLowerCase(),(n=e.id&&this.escapeCssNames(new String(e.id)))&&0"!==t&&":"!==t&&","!==t&&"+"!==t&&"~"!==t||(0"===n?i[r]=2:"+"===n||"~"===n?i[r]=3:":"!==n&&"."!==n&&"#"!==n&&" "!==n&&">"!==n&&"+"!==n&&"~"!==n?i[r]=4:"."===n?i[r]=5:(n="#")?(i[r]=6,s.match(/\d{3,}/)&&(i[r]=2.5)):i[r]=0,i[r]+=r*t,r++;return i},e.prototype.orderFromPriorities=function(e){var t,n,r,i,o,s,a;for(r=new Array,n=new Array,t=i=0,s=e.length;0<=s?i/g," > ").replace(/\s*(>\s*)+/g," > ").replace(/,/g," , ").replace(/\s+/g," ").replace(/^\s+|\s+$/g,"").replace(/\s*,$/g,"").replace(/^\s*,\s*/g,"").replace(/\s*>$/g,"").replace(/^>\s*/g,"").replace(/[\+\~\>]\s*,/g,",").replace(/[\+\~]\s*>/g,">").replace(/\s*(,\s*)+/g," , ");return t},e.prototype.getPathsFor=function(e){var t,n,r,i;for(n=[],r=0,i=e.length;r\|\/]/g,function(e){return"\\"+e}).replace(/\s+/,"")}catch(t){return t,window.console&&(console.log("---"),console.log("exception in escapeCssNames"),console.log(e),console.log("---")),""}},e.prototype.childElemNumber=function(e){var t;for(t=0;e.previousSibling&&(e=e.previousSibling);)1===e.nodeType&&t++;return t},e.prototype.siblingsWithoutTextNodes=function(e){var t,n,r,i,o;for(t=[],n=0,r=(o=e.parentNode.childNodes).length;n "}return this.cleanCss(o)},e.prototype.cssDescriptor=function(e){var t,n,r,i,o,s;if(o=e.nodeName.toLowerCase(),(n=e.id&&this.escapeCssNames(new String(e.id)))&&0"!==t&&":"!==t&&","!==t&&"+"!==t&&"~"!==t||(0"===n?s[r]=2:"+"===n||"~"===n?s[r]=3:":"!==n&&"."!==n&&"#"!==n&&" "!==n&&">"!==n&&"+"!==n&&"~"!==n?s[r]=4:"."===n?s[r]=5:(n="#")?(s[r]=6,l.match(/\d{3,}/)&&(s[r]=2.5)):s[r]=0,s[r]+=r*t,r++;return s},e.prototype.orderFromPriorities=function(e){var t,n,r,i,o,s,a;for(a=new Array,i=new Array,t=n=0,o=e.length;0<=o?n/g," > ").replace(/\s*(>\s*)+/g," > ").replace(/,/g," , ").replace(/\s+/g," ").replace(/^\s+|\s+$/g,"").replace(/\s*,$/g,"").replace(/^\s*,\s*/g,"").replace(/\s*>$/g,"").replace(/^>\s*/g,"").replace(/[\+\~\>]\s*,/g,",").replace(/[\+\~]\s*>/g,">").replace(/\s*(,\s*)+/g," , ");return t},e.prototype.getPathsFor=function(e){var t,n,r,i;for(i=[],t=0,n=e.length;t").addClass("selectorgadget_border").css("height",e).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.b_bottom=jQuerySG("
").addClass("selectorgadget_border").addClass("selectorgadget_bottom_border").css("height",this.px(this.border_width+6)).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.b_left=jQuerySG("
").addClass("selectorgadget_border").css("width",e).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.b_right=jQuerySG("
").addClass("selectorgadget_border").css("width",e).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.addBorderToDom()},t.prototype.addBorderToDom=function(){return document.body.appendChild(this.b_top.get(0)),document.body.appendChild(this.b_bottom.get(0)),document.body.appendChild(this.b_left.get(0)),document.body.appendChild(this.b_right.get(0))},t.prototype.removeBorderFromDom=function(){if(this.b_top)return this.b_top.remove(),this.b_bottom.remove(),this.b_left.remove(),this.b_right.remove(),this.b_top=this.b_bottom=this.b_left=this.b_right=null},t.prototype.selectable=function(e){return!this.css_restriction||this.css_restriction&&jQuerySG(e).is(this.css_restriction)},t.prototype.sgMouseover=function(e){var t,n,r;return!!(t=e.data.self).unbound||(this===document.body||this===document.body.parentNode||(r=jQuerySG(this),t.unhighlightIframes(),r.is("iframe")&&t.highlightIframe(r,e),"d"!==t.special_mode?null!==(n=t.firstSelectedOrSuggestedParent(this))&&n!==this&&t.selectable(n)?t.makeBorders(n,!0):t.selectable(r)&&t.makeBorders(this):jQuerySG(".selectorgadget_selected",this).get(0)||t.selectable(r)&&t.makeBorders(this)),!1)},t.prototype.firstSelectedOrSuggestedParent=function(e){if(e,jQuerySG(e).hasClass("selectorgadget_suggested")||jQuerySG(e).hasClass("selectorgadget_selected"))return e;for(;e.parentNode&&(e=e.parentNode);)if(-1===jQuerySG.inArray(e,this.restricted_elements)&&(jQuerySG(e).hasClass("selectorgadget_suggested")||jQuerySG(e).hasClass("selectorgadget_selected")))return e;return null},t.prototype.sgMouseout=function(e){var t;return!!(t=e.data.self).unbound||(this===document.body||this===document.body.parentNode||(jQuerySG(this),t.removeBorders()),!1)},t.prototype.highlightIframe=function(e,t){var n,r,i,o,s,a;i=e.offset(),o=this,a=jQuerySG(t.target),n=jQuerySG("
").css("position","absolute").css("z-index","99998").css("width",this.px(e.outerWidth())).css("height",this.px(e.outerHeight())).css("top",this.px(i.top)).css("left",this.px(i.left)).css("background-color","#AAA").css("opacity","0.6").addClass("selectorgadget_iframe").addClass("selectorgadget_clean"),(r=jQuerySG("
This is an iframe. To select in it,
").addClass("selectorgadget_iframe_info").addClass("selectorgadget_iframe").addClass("selectorgadget_clean")).css({width:"200px",border:"1px solid #888"},{padding:"5px","background-color":"white",position:"absolute","z-index":"99999",top:this.px(i.top+e.outerHeight()/4),left:this.px(i.left+(e.outerWidth()-200)/2),height:"150px"}),s=null;try{s=e.contents().get(0).location.href}catch(l){s=e.attr("src")}return r.append(jQuerySG("click here to open it").attr("href",s)),r.append(jQuerySG(", then relaunch SelectorGadget.")),document.body.appendChild(r.get(0)),n.click(function(){if(o.selectable(a))return a.mousedown()}),document.body.appendChild(n.get(0))},t.prototype.unhighlightIframes=function(){return jQuerySG(".selectorgadget_iframe").remove()},t.prototype.sgMousedown=function(e){var t,n,r,i,o;return!!(n=e.data.self).unbound||(t=this,(o=jQuerySG(t)).hasClass("selectorgadget_border")&&(t=t.target_elem||t,o=jQuerySG(t)),t!==document.body&&t!==document.body.parentNode?("d"!==n.special_mode?null!==(r=n.firstSelectedOrSuggestedParent(t))&&r!==t&&(t=r,o=jQuerySG(t)):jQuerySG(".selectorgadget_selected",this).get(0)&&n.blockClicksOn(t),n.selectable(o)?(o.hasClass("selectorgadget_selected")?(o.removeClass("selectorgadget_selected"),n.selected.splice(jQuerySG.inArray(t,n.selected),1)):o.hasClass("selectorgadget_rejected")?(o.removeClass("selectorgadget_rejected"),n.rejected.splice(jQuerySG.inArray(t,n.rejected),1)):o.hasClass("selectorgadget_suggested")?(o.addClass("selectorgadget_rejected"),n.rejected.push(t)):(o.addClass("selectorgadget_selected"),n.selected.push(t)),n.clearSuggested(),i=n.prediction_helper.predictCss(jQuerySG(n.selected),jQuerySG(n.rejected.concat(n.restricted_elements))),n.suggestPredicted(i),n.setPath(i),n.removeBorders(),n.blockClicksOn(t),o.trigger("mouseover.sg",{self:n})):(n.removeBorders(),n.blockClicksOn(t)),!1):void 0)},t.prototype.setupEventHandlers=function(){return jQuerySG("*:not(.selectorgadget_ignore)").bind("mouseover.sg",{self:this},this.sgMouseover),jQuerySG("*:not(.selectorgadget_ignore)").bind("mouseout.sg",{self:this},this.sgMouseout),jQuerySG("*:not(.selectorgadget_ignore)").bind("mousedown.sg",{self:this},this.sgMousedown),jQuerySG("html").bind("keydown.sg",{self:this},this.listenForActionKeys),jQuerySG("html").bind("keyup.sg",{self:this},this.clearActionKeys)},t.prototype.listenForActionKeys=function(e){var t;return!!(t=e.data.self).unbound||(16===e.keyCode||68===e.keyCode?(t.special_mode="d",t.removeBorders()):void 0)},t.prototype.clearActionKeys=function(e){var t;return!!(t=e.data.self).unbound||(t.removeBorders(),t.special_mode=null)},t.prototype.blockClicksOn=function(e){var t,n;return n=(e=jQuerySG(e)).offset(),t=jQuerySG("
").css("position","absolute").css("z-index","9999999").css("width",this.px(e.outerWidth())).css("height",this.px(e.outerHeight())).css("top",this.px(n.top)).css("left",this.px(n.left)).css("background-color",""),document.body.appendChild(t.get(0)),setTimeout(function(){return t.remove()},400),!1},t.prototype.setMode=function(e){return"browse"===e?this.removeEventHandlers():"interactive"===e&&this.setupEventHandlers(),this.clearSelected()},t.prototype.suggestPredicted=function(e){var t;if(e&&""!==e&&(t=0,jQuerySG(e).each(function(){if(t+=1,!jQuerySG(this).hasClass("selectorgadget_selected")&&!jQuerySG(this).hasClass("selectorgadget_ignore")&&!jQuerySG(this).hasClass("selectorgadget_rejected"))return jQuerySG(this).addClass("selectorgadget_suggested")}),this.clear_button))return 0").attr("id","selectorgadget_main").addClass("selectorgadget_bottom").addClass("selectorgadget_ignore"),this.useRemoteInterface()?(this.path_output_field={value:null},this.remote_data={},this.updateRemoteInterface()):this.makeStandardInterface(),jQuerySG("body").append(this.sg_div)},t.prototype.makeStandardInterface=function(){var e,t;return t=this,e=jQuerySG("").attr("id","selectorgadget_path_field").addClass("selectorgadget_ignore").addClass("selectorgadget_input_field").keydown(function(e){if(13===e.keyCode)return t.refreshFromPath(e)}).focus(function(){return jQuerySG(this).select()}),this.sg_div.append(e),this.clear_button=jQuerySG('').bind("click",{self:this},this.clearEverything).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field"),this.sg_div.append(this.clear_button),this.sg_div.append(jQuerySG('').click(function(){return t.sg_div.hasClass("selectorgadget_top")?t.sg_div.removeClass("selectorgadget_top").addClass("selectorgadget_bottom"):t.sg_div.removeClass("selectorgadget_bottom").addClass("selectorgadget_top")}).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.sg_div.append(jQuerySG('').bind("click",{self:this},this.showXPath).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.sg_div.append(jQuerySG('').bind("click",{self:this},this.showHelp).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.sg_div.append(jQuerySG('').bind("click",{self:this},this.unbindAndRemoveInterface).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.path_output_field=e.get(0)},t.prototype.removeInterface=function(){return this.sg_div.remove(),this.sg_div=null},t.prototype.unbind=function(e){var t;return(t=e&&e.data&&e.data.self||this).unbound=!0,t.removeBorderFromDom(),t.clearSelected()},t.prototype.unbindAndRemoveInterface=function(e){var t;return(t=e&&e.data&&e.data.self||this).unbind(),t.removeInterface()},t.prototype.setOutputMode=function(e,t){return(e&&e.data&&e.data.self||this).output_mode=e&&e.data&&e.data.mode||t},t.prototype.rebind=function(){return this.unbound=!1,this.clearEverything(),this.setupBorders()},t.prototype.rebindAndMakeInterface=function(){return this.makeInterface(),this.rebind()},t.prototype.randBetween=function(e,t){return Math.floor(Math.random()*t)+e},t.toggle=function(e){return window.selector_gadget?window.selector_gadget.unbound?window.selector_gadget.rebindAndMakeInterface():window.selector_gadget.unbindAndRemoveInterface():(window.selector_gadget=new t,window.selector_gadget.makeInterface(),window.selector_gadget.clearEverything(),window.selector_gadget.setMode("interactive"),!1!==(null!=e?e.analytics:void 0)&&window.selector_gadget.analytics()),jQuerySG(".selector_gadget_loading").remove()},t.prototype.analytics=function(){var e,t,n,r,i,o,s;return i="UA-148948-9",o=encodeURIComponent("www.selectorgadget.com"),s=this.randBetween(1e9,9999999999),e=this.randBetween(1e7,99999999),t=this.randBetween(1e9,2147483647),n=Math.round((new Date).getTime()/1e3),r="http://www.google-analytics.com/__utm.gif?utmwv=1&utmn="+s+"&utmsr=-&utmsc=-&utmul=-&utmje=0&utmfl=-&utmdt=-&utmhn="+o+"&utmr="+encodeURIComponent(window.location.href)+"&utmp="+"sg"+"&utmac="+i+"&utmcc=__utma%3D"+e+"."+t+"."+n+"."+n+"."+n+".2%3B%2B__utmb%3D"+e+"%3B%2B__utmc%3D"+e+"%3B%2B__utmz%3D"+e+"."+n+".2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D"+e+"."+"-"+"%3B",document.body.appendChild(jQuerySG("").attr("src",r).get(0))},t}()}.call(this); \ No newline at end of file + */ +function(){window.SelectorGadget=function(){function t(){}return t.prototype.border_width=5,t.prototype.border_padding=2,t.prototype.b_top=null,t.prototype.b_left=null,t.prototype.b_right=null,t.prototype.b_bottom=null,t.prototype.selected=[],t.prototype.rejected=[],t.prototype.special_mode=null,t.prototype.path_output_field=null,t.prototype.sg_div=null,t.prototype.ignore_class="selectorgadget_ignore",t.prototype.unbound=!1,t.prototype.prediction_helper=new DomPredictionHelper,t.prototype.restricted_elements=jQuerySG.map(["html","body","head","base"],function(e){return jQuerySG(e).get(0)}),t.prototype.makeBorders=function(e,t){var n,r,i,o,s,a,l;return this.removeBorders(),this.setupBorders(),s=e.parentNode?e.parentNode.tagName.toLowerCase()+" "+e.tagName.toLowerCase():e.tagName.toLowerCase(),a=(o=(n=jQuerySG(e)).offset()).top,i=o.left,l=n.outerWidth(),r=n.outerHeight(),this.b_top.css("width",this.px(l+2*this.border_padding+2*this.border_width)).css("top",this.px(a-this.border_width-this.border_padding)).css("left",this.px(i-this.border_padding-this.border_width)),this.b_bottom.css("width",this.px(l+2*this.border_padding+2*this.border_width-5)).css("top",this.px(a+r+this.border_padding)).css("left",this.px(i-this.border_padding-this.border_width)).text(s),this.b_left.css("height",this.px(r+2*this.border_padding)).css("top",this.px(a-this.border_padding)).css("left",this.px(i-this.border_padding-this.border_width)),this.b_right.css("height",this.px(r+2*this.border_padding)).css("top",this.px(a-this.border_padding)).css("left",this.px(i+l+this.border_padding)),this.b_right.get(0).target_elem=this.b_left.get(0).target_elem=this.b_top.get(0).target_elem=this.b_bottom.get(0).target_elem=e,t||n.hasClass("selectorgadget_suggested")||n.hasClass("selectorgadget_selected")?(this.b_top.addClass("selectorgadget_border_red"),this.b_bottom.addClass("selectorgadget_border_red"),this.b_left.addClass("selectorgadget_border_red"),this.b_right.addClass("selectorgadget_border_red")):this.b_top.hasClass("selectorgadget_border_red")&&(this.b_top.removeClass("selectorgadget_border_red"),this.b_bottom.removeClass("selectorgadget_border_red"),this.b_left.removeClass("selectorgadget_border_red"),this.b_right.removeClass("selectorgadget_border_red")),this.showBorders()},t.prototype.px=function(e){return e+"px"},t.prototype.showBorders=function(){return this.b_top.show(),this.b_bottom.show(),this.b_left.show(),this.b_right.show()},t.prototype.removeBorders=function(){if(this.b_top)return this.b_top.hide(),this.b_bottom.hide(),this.b_left.hide(),this.b_right.hide()},t.prototype.setupBorders=function(){var e;if(!this.b_top)return e=this.border_width+"px",this.b_top=jQuerySG("
").addClass("selectorgadget_border").css("height",e).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.b_bottom=jQuerySG("
").addClass("selectorgadget_border").addClass("selectorgadget_bottom_border").css("height",this.px(this.border_width+6)).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.b_left=jQuerySG("
").addClass("selectorgadget_border").css("width",e).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.b_right=jQuerySG("
").addClass("selectorgadget_border").css("width",e).hide().bind("mousedown.sg",{self:this},this.sgMousedown),this.addBorderToDom()},t.prototype.addBorderToDom=function(){return document.body.appendChild(this.b_top.get(0)),document.body.appendChild(this.b_bottom.get(0)),document.body.appendChild(this.b_left.get(0)),document.body.appendChild(this.b_right.get(0))},t.prototype.removeBorderFromDom=function(){if(this.b_top)return this.b_top.remove(),this.b_bottom.remove(),this.b_left.remove(),this.b_right.remove(),this.b_top=this.b_bottom=this.b_left=this.b_right=null},t.prototype.selectable=function(e){return!this.css_restriction||this.css_restriction&&jQuerySG(e).is(this.css_restriction)},t.prototype.sgMouseover=function(e){var t,n,r;return!!(t=e.data.self).unbound||(this===document.body||this===document.body.parentNode||(r=jQuerySG(this),t.unhighlightIframes(),r.is("iframe")&&t.highlightIframe(r,e),"d"!==t.special_mode?null!==(n=t.firstSelectedOrSuggestedParent(this))&&n!==this&&t.selectable(n)?t.makeBorders(n,!0):t.selectable(r)&&t.makeBorders(this):jQuerySG(".selectorgadget_selected",this).get(0)||t.selectable(r)&&t.makeBorders(this)),!1)},t.prototype.firstSelectedOrSuggestedParent=function(e){if(e,jQuerySG(e).hasClass("selectorgadget_suggested")||jQuerySG(e).hasClass("selectorgadget_selected"))return e;for(;e.parentNode&&(e=e.parentNode);)if(-1===jQuerySG.inArray(e,this.restricted_elements)&&(jQuerySG(e).hasClass("selectorgadget_suggested")||jQuerySG(e).hasClass("selectorgadget_selected")))return e;return null},t.prototype.sgMouseout=function(e){var t;return!!(t=e.data.self).unbound||(this===document.body||this===document.body.parentNode||(jQuerySG(this),t.removeBorders()),!1)},t.prototype.highlightIframe=function(e,t){var n,r,i,o,s,a;i=e.offset(),o=this,a=jQuerySG(t.target),n=jQuerySG("
").css("position","absolute").css("z-index","99998").css("width",this.px(e.outerWidth())).css("height",this.px(e.outerHeight())).css("top",this.px(i.top)).css("left",this.px(i.left)).css("background-color","#AAA").css("opacity","0.6").addClass("selectorgadget_iframe").addClass("selectorgadget_clean"),(r=jQuerySG("
This is an iframe. To select in it,
").addClass("selectorgadget_iframe_info").addClass("selectorgadget_iframe").addClass("selectorgadget_clean")).css({width:"200px",border:"1px solid #888"},{padding:"5px","background-color":"white",position:"absolute","z-index":"99999",top:this.px(i.top+e.outerHeight()/4),left:this.px(i.left+(e.outerWidth()-200)/2),height:"150px"}),s=null;try{s=e.contents().get(0).location.href}catch(l){l,s=e.attr("src")}return r.append(jQuerySG("click here to open it").attr("href",s)),r.append(jQuerySG(", then relaunch SelectorGadget.")),document.body.appendChild(r.get(0)),n.click(function(){if(o.selectable(a))return a.mousedown()}),document.body.appendChild(n.get(0))},t.prototype.unhighlightIframes=function(){return jQuerySG(".selectorgadget_iframe").remove()},t.prototype.sgMousedown=function(e){var t,n,r,i,o;return!!(n=e.data.self).unbound||(t=this,(o=jQuerySG(t)).hasClass("selectorgadget_border")&&(t=t.target_elem||t,o=jQuerySG(t)),t!==document.body&&t!==document.body.parentNode?("d"!==n.special_mode?null!==(r=n.firstSelectedOrSuggestedParent(t))&&r!==t&&(t=r,o=jQuerySG(t)):jQuerySG(".selectorgadget_selected",this).get(0)&&n.blockClicksOn(t),n.selectable(o)?(o.hasClass("selectorgadget_selected")?(o.removeClass("selectorgadget_selected"),n.selected.splice(jQuerySG.inArray(t,n.selected),1)):o.hasClass("selectorgadget_rejected")?(o.removeClass("selectorgadget_rejected"),n.rejected.splice(jQuerySG.inArray(t,n.rejected),1)):o.hasClass("selectorgadget_suggested")?(o.addClass("selectorgadget_rejected"),n.rejected.push(t)):(o.addClass("selectorgadget_selected"),n.selected.push(t)),n.clearSuggested(),i=n.prediction_helper.predictCss(jQuerySG(n.selected),jQuerySG(n.rejected.concat(n.restricted_elements))),n.suggestPredicted(i),n.setPath(i),n.removeBorders(),n.blockClicksOn(t),o.trigger("mouseover.sg",{self:n})):(n.removeBorders(),n.blockClicksOn(t)),!1):void 0)},t.prototype.setupEventHandlers=function(){return jQuerySG("*:not(.selectorgadget_ignore)").bind("mouseover.sg",{self:this},this.sgMouseover),jQuerySG("*:not(.selectorgadget_ignore)").bind("mouseout.sg",{self:this},this.sgMouseout),jQuerySG("*:not(.selectorgadget_ignore)").bind("mousedown.sg",{self:this},this.sgMousedown),jQuerySG("html").bind("keydown.sg",{self:this},this.listenForActionKeys),jQuerySG("html").bind("keyup.sg",{self:this},this.clearActionKeys)},t.prototype.listenForActionKeys=function(e){var t;return!!(t=e.data.self).unbound||(16===e.keyCode||68===e.keyCode?(t.special_mode="d",t.removeBorders()):void 0)},t.prototype.clearActionKeys=function(e){var t;return!!(t=e.data.self).unbound||(t.removeBorders(),t.special_mode=null)},t.prototype.blockClicksOn=function(e){var t,n;return n=(e=jQuerySG(e)).offset(),t=jQuerySG("
").css("position","absolute").css("z-index","9999999").css("width",this.px(e.outerWidth())).css("height",this.px(e.outerHeight())).css("top",this.px(n.top)).css("left",this.px(n.left)).css("background-color",""),document.body.appendChild(t.get(0)),setTimeout(function(){return t.remove()},400),!1},t.prototype.setMode=function(e){return"browse"===e?this.removeEventHandlers():"interactive"===e&&this.setupEventHandlers(),this.clearSelected()},t.prototype.suggestPredicted=function(e){var t;if(e&&""!==e&&(t=0,jQuerySG(e).each(function(){if(t+=1,!jQuerySG(this).hasClass("selectorgadget_selected")&&!jQuerySG(this).hasClass("selectorgadget_ignore")&&!jQuerySG(this).hasClass("selectorgadget_rejected"))return jQuerySG(this).addClass("selectorgadget_suggested")}),this.clear_button))return 0").attr("id","selectorgadget_main").addClass("selectorgadget_bottom").addClass("selectorgadget_ignore"),this.useRemoteInterface()?(this.path_output_field={value:null},this.remote_data={},this.updateRemoteInterface()):this.makeStandardInterface(),jQuerySG("body").append(this.sg_div)},t.prototype.makeStandardInterface=function(){var e,t;return t=this,e=jQuerySG("").attr("id","selectorgadget_path_field").addClass("selectorgadget_ignore").addClass("selectorgadget_input_field").keydown(function(e){if(13===e.keyCode)return t.refreshFromPath(e)}).focus(function(){return jQuerySG(this).select()}),this.sg_div.append(e),this.clear_button=jQuerySG('').bind("click",{self:this},this.clearEverything).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field"),this.sg_div.append(this.clear_button),this.sg_div.append(jQuerySG('').click(function(){return t.sg_div.hasClass("selectorgadget_top")?t.sg_div.removeClass("selectorgadget_top").addClass("selectorgadget_bottom"):t.sg_div.removeClass("selectorgadget_bottom").addClass("selectorgadget_top")}).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.sg_div.append(jQuerySG('').bind("click",{self:this},this.showXPath).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.sg_div.append(jQuerySG('').bind("click",{self:this},this.showHelp).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.sg_div.append(jQuerySG('').bind("click",{self:this},this.unbindAndRemoveInterface).addClass("selectorgadget_ignore").addClass("selectorgadget_input_field")),this.path_output_field=e.get(0)},t.prototype.removeInterface=function(){return this.sg_div.remove(),this.sg_div=null},t.prototype.unbind=function(e){var t;return(t=e&&e.data&&e.data.self||this).unbound=!0,t.removeBorderFromDom(),t.clearSelected()},t.prototype.unbindAndRemoveInterface=function(e){var t;return(t=e&&e.data&&e.data.self||this).unbind(),t.removeInterface()},t.prototype.setOutputMode=function(e,t){return(e&&e.data&&e.data.self||this).output_mode=e&&e.data&&e.data.mode||t},t.prototype.rebind=function(){return this.unbound=!1,this.clearEverything(),this.setupBorders()},t.prototype.rebindAndMakeInterface=function(){return this.makeInterface(),this.rebind()},t.prototype.randBetween=function(e,t){return Math.floor(Math.random()*t)+e},t.toggle=function(e){return window.selector_gadget?window.selector_gadget.unbound?window.selector_gadget.rebindAndMakeInterface():window.selector_gadget.unbindAndRemoveInterface():(window.selector_gadget=new t,window.selector_gadget.makeInterface(),window.selector_gadget.clearEverything(),window.selector_gadget.setMode("interactive"),!1!==(null!=e?e.analytics:void 0)&&window.selector_gadget.analytics()),jQuerySG(".selector_gadget_loading").remove()},t.prototype.analytics=function(){var e,t,n,r,i,o,s;return i="UA-148948-9",o=encodeURIComponent("www.selectorgadget.com"),s=this.randBetween(1e9,9999999999),e=this.randBetween(1e7,99999999),t=this.randBetween(1e9,2147483647),n=Math.round((new Date).getTime()/1e3),r="http://www.google-analytics.com/__utm.gif?utmwv=1&utmn="+s+"&utmsr=-&utmsc=-&utmul=-&utmje=0&utmfl=-&utmdt=-&utmhn="+o+"&utmr="+encodeURIComponent(window.location.href)+"&utmp="+"sg"+"&utmac="+i+"&utmcc=__utma%3D"+e+"."+t+"."+n+"."+n+"."+n+".2%3B%2B__utmb%3D"+e+"%3B%2B__utmc%3D"+e+"%3B%2B__utmz%3D"+e+"."+n+".2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D"+e+"."+"-"+"%3B",document.body.appendChild(jQuerySG("").attr("src",r).get(0))},t}()}.call(this); \ No newline at end of file diff --git a/spec/compiled/core-spec.js b/spec/compiled/core-spec.js index 23762c6..7669260 100644 --- a/spec/compiled/core-spec.js +++ b/spec/compiled/core-spec.js @@ -1,5 +1,4 @@ (function() { - describe("SelectorGadget", function() { var sg; sg = null; diff --git a/spec/compiled/core.js b/spec/compiled/core.js new file mode 100644 index 0000000..bf557c5 --- /dev/null +++ b/spec/compiled/core.js @@ -0,0 +1,627 @@ + +/* + The MIT License + + Copyright (c) 2012 Andrew Cantino + Copyright (c) 2009 Andrew Cantino & Kyle Maxwell + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +(function() { + var SelectorGadget; + + window.SelectorGadget = SelectorGadget = (function() { + function SelectorGadget() {} + + SelectorGadget.prototype.border_width = 5; + + SelectorGadget.prototype.border_padding = 2; + + SelectorGadget.prototype.b_top = null; + + SelectorGadget.prototype.b_left = null; + + SelectorGadget.prototype.b_right = null; + + SelectorGadget.prototype.b_bottom = null; + + SelectorGadget.prototype.selected = []; + + SelectorGadget.prototype.rejected = []; + + SelectorGadget.prototype.special_mode = null; + + SelectorGadget.prototype.path_output_field = null; + + SelectorGadget.prototype.sg_div = null; + + SelectorGadget.prototype.ignore_class = 'selectorgadget_ignore'; + + SelectorGadget.prototype.unbound = false; + + SelectorGadget.prototype.prediction_helper = new DomPredictionHelper(); + + SelectorGadget.prototype.restricted_elements = jQuerySG.map(['html', 'body', 'head', 'base'], function(selector) { + return jQuerySG(selector).get(0); + }); + + SelectorGadget.prototype.makeBorders = function(orig_elem, makeRed) { + var elem, height, left, p, path_to_show, top, width; + this.removeBorders(); + this.setupBorders(); + if (orig_elem.parentNode) { + path_to_show = orig_elem.parentNode.tagName.toLowerCase() + ' ' + orig_elem.tagName.toLowerCase(); + } else { + path_to_show = orig_elem.tagName.toLowerCase(); + } + elem = jQuerySG(orig_elem); + p = elem.offset(); + top = p.top; + left = p.left; + width = elem.outerWidth(); + height = elem.outerHeight(); + this.b_top.css('width', this.px(width + this.border_padding * 2 + this.border_width * 2)).css('top', this.px(top - this.border_width - this.border_padding)).css('left', this.px(left - this.border_padding - this.border_width)); + this.b_bottom.css('width', this.px(width + this.border_padding * 2 + this.border_width * 2 - 5)).css('top', this.px(top + height + this.border_padding)).css('left', this.px(left - this.border_padding - this.border_width)).text(path_to_show); + this.b_left.css('height', this.px(height + this.border_padding * 2)).css('top', this.px(top - this.border_padding)).css('left', this.px(left - this.border_padding - this.border_width)); + this.b_right.css('height', this.px(height + this.border_padding * 2)).css('top', this.px(top - this.border_padding)).css('left', this.px(left + width + this.border_padding)); + this.b_right.get(0).target_elem = this.b_left.get(0).target_elem = this.b_top.get(0).target_elem = this.b_bottom.get(0).target_elem = orig_elem; + if (makeRed || elem.hasClass("selectorgadget_suggested") || elem.hasClass("selectorgadget_selected")) { + this.b_top.addClass('selectorgadget_border_red'); + this.b_bottom.addClass('selectorgadget_border_red'); + this.b_left.addClass('selectorgadget_border_red'); + this.b_right.addClass('selectorgadget_border_red'); + } else { + if (this.b_top.hasClass('selectorgadget_border_red')) { + this.b_top.removeClass('selectorgadget_border_red'); + this.b_bottom.removeClass('selectorgadget_border_red'); + this.b_left.removeClass('selectorgadget_border_red'); + this.b_right.removeClass('selectorgadget_border_red'); + } + } + return this.showBorders(); + }; + + SelectorGadget.prototype.px = function(p) { + return p + 'px'; + }; + + SelectorGadget.prototype.showBorders = function() { + this.b_top.show(); + this.b_bottom.show(); + this.b_left.show(); + return this.b_right.show(); + }; + + SelectorGadget.prototype.removeBorders = function() { + if (this.b_top) { + this.b_top.hide(); + this.b_bottom.hide(); + this.b_left.hide(); + return this.b_right.hide(); + } + }; + + SelectorGadget.prototype.setupBorders = function() { + var width; + if (!this.b_top) { + width = this.border_width + 'px'; + this.b_top = jQuerySG('
').addClass('selectorgadget_border').css('height', width).hide().bind("mousedown.sg", { + 'self': this + }, this.sgMousedown); + this.b_bottom = jQuerySG('
').addClass('selectorgadget_border').addClass('selectorgadget_bottom_border').css('height', this.px(this.border_width + 6)).hide().bind("mousedown.sg", { + 'self': this + }, this.sgMousedown); + this.b_left = jQuerySG('
').addClass('selectorgadget_border').css('width', width).hide().bind("mousedown.sg", { + 'self': this + }, this.sgMousedown); + this.b_right = jQuerySG('
').addClass('selectorgadget_border').css('width', width).hide().bind("mousedown.sg", { + 'self': this + }, this.sgMousedown); + return this.addBorderToDom(); + } + }; + + SelectorGadget.prototype.addBorderToDom = function() { + document.body.appendChild(this.b_top.get(0)); + document.body.appendChild(this.b_bottom.get(0)); + document.body.appendChild(this.b_left.get(0)); + return document.body.appendChild(this.b_right.get(0)); + }; + + SelectorGadget.prototype.removeBorderFromDom = function() { + if (this.b_top) { + this.b_top.remove(); + this.b_bottom.remove(); + this.b_left.remove(); + this.b_right.remove(); + return this.b_top = this.b_bottom = this.b_left = this.b_right = null; + } + }; + + SelectorGadget.prototype.selectable = function(elem) { + return !this.css_restriction || (this.css_restriction && jQuerySG(elem).is(this.css_restriction)); + }; + + SelectorGadget.prototype.sgMouseover = function(e) { + var gadget, parent, self; + gadget = e.data.self; + if (gadget.unbound) { + return true; + } + if (this === document.body || this === document.body.parentNode) { + return false; + } + self = jQuerySG(this); + gadget.unhighlightIframes(); + if (self.is("iframe")) { + gadget.highlightIframe(self, e); + } + if (gadget.special_mode !== 'd') { + parent = gadget.firstSelectedOrSuggestedParent(this); + if (parent !== null && parent !== this && gadget.selectable(parent)) { + gadget.makeBorders(parent, true); + } else { + if (gadget.selectable(self)) { + gadget.makeBorders(this); + } + } + } else { + if (!jQuerySG('.selectorgadget_selected', this).get(0)) { + if (gadget.selectable(self)) { + gadget.makeBorders(this); + } + } + } + return false; + }; + + SelectorGadget.prototype.firstSelectedOrSuggestedParent = function(elem) { + var orig; + orig = elem; + if (jQuerySG(elem).hasClass('selectorgadget_suggested') || jQuerySG(elem).hasClass('selectorgadget_selected')) { + return elem; + } + while (elem.parentNode && (elem = elem.parentNode)) { + if (jQuerySG.inArray(elem, this.restricted_elements) === -1) { + if (jQuerySG(elem).hasClass('selectorgadget_suggested') || jQuerySG(elem).hasClass('selectorgadget_selected')) { + return elem; + } + } + } + return null; + }; + + SelectorGadget.prototype.sgMouseout = function(e) { + var elem, gadget; + gadget = e.data.self; + if (gadget.unbound) { + return true; + } + if (this === document.body || this === document.body.parentNode) { + return false; + } + elem = jQuerySG(this); + gadget.removeBorders(); + return false; + }; + + SelectorGadget.prototype.highlightIframe = function(elem, click) { + var block, e, instructions, p, self, src, target; + p = elem.offset(); + self = this; + target = jQuerySG(click.target); + block = jQuerySG('
').css('position', 'absolute').css('z-index', '99998').css('width', this.px(elem.outerWidth())).css('height', this.px(elem.outerHeight())).css('top', this.px(p.top)).css('left', this.px(p.left)).css('background-color', '#AAA').css('opacity', '0.6').addClass("selectorgadget_iframe").addClass('selectorgadget_clean'); + instructions = jQuerySG("
This is an iframe. To select in it,
").addClass("selectorgadget_iframe_info").addClass("selectorgadget_iframe").addClass('selectorgadget_clean'); + instructions.css({ + width: "200px", + border: "1px solid #888" + }, { + padding: "5px", + "background-color": "white", + position: "absolute", + "z-index": "99999", + top: this.px(p.top + (elem.outerHeight() / 4.0)), + left: this.px(p.left + (elem.outerWidth() - 200) / 2.0), + height: "150px" + }); + src = null; + try { + src = elem.contents().get(0).location.href; + } catch (error) { + e = error; + src = elem.attr("src"); + } + instructions.append(jQuerySG("click here to open it").attr("href", src)); + instructions.append(jQuerySG(", then relaunch SelectorGadget.")); + document.body.appendChild(instructions.get(0)); + block.click(function() { + if (self.selectable(target)) { + return target.mousedown(); + } + }); + return document.body.appendChild(block.get(0)); + }; + + SelectorGadget.prototype.unhighlightIframes = function(elem, click) { + return jQuerySG(".selectorgadget_iframe").remove(); + }; + + SelectorGadget.prototype.sgMousedown = function(e) { + var elem, gadget, potential_elem, prediction, w_elem; + gadget = e.data.self; + if (gadget.unbound) { + return true; + } + elem = this; + w_elem = jQuerySG(elem); + if (w_elem.hasClass('selectorgadget_border')) { + elem = elem.target_elem || elem; + w_elem = jQuerySG(elem); + } + if (elem === document.body || elem === document.body.parentNode) { + return; + } + if (gadget.special_mode !== 'd') { + potential_elem = gadget.firstSelectedOrSuggestedParent(elem); + if (potential_elem !== null && potential_elem !== elem) { + elem = potential_elem; + w_elem = jQuerySG(elem); + } + } else { + if (jQuerySG('.selectorgadget_selected', this).get(0)) { + gadget.blockClicksOn(elem); + } + } + if (!gadget.selectable(w_elem)) { + gadget.removeBorders(); + gadget.blockClicksOn(elem); + return false; + } + if (w_elem.hasClass('selectorgadget_selected')) { + w_elem.removeClass('selectorgadget_selected'); + gadget.selected.splice(jQuerySG.inArray(elem, gadget.selected), 1); + } else if (w_elem.hasClass("selectorgadget_rejected")) { + w_elem.removeClass('selectorgadget_rejected'); + gadget.rejected.splice(jQuerySG.inArray(elem, gadget.rejected), 1); + } else if (w_elem.hasClass("selectorgadget_suggested")) { + w_elem.addClass('selectorgadget_rejected'); + gadget.rejected.push(elem); + } else { + w_elem.addClass('selectorgadget_selected'); + gadget.selected.push(elem); + } + gadget.clearSuggested(); + prediction = gadget.prediction_helper.predictCss(jQuerySG(gadget.selected), jQuerySG(gadget.rejected.concat(gadget.restricted_elements))); + gadget.suggestPredicted(prediction); + gadget.setPath(prediction); + gadget.removeBorders(); + gadget.blockClicksOn(elem); + w_elem.trigger("mouseover.sg", { + 'self': gadget + }); + return false; + }; + + SelectorGadget.prototype.setupEventHandlers = function() { + jQuerySG("*:not(.selectorgadget_ignore)").bind("mouseover.sg", { + 'self': this + }, this.sgMouseover); + jQuerySG("*:not(.selectorgadget_ignore)").bind("mouseout.sg", { + 'self': this + }, this.sgMouseout); + jQuerySG("*:not(.selectorgadget_ignore)").bind("mousedown.sg", { + 'self': this + }, this.sgMousedown); + jQuerySG("html").bind("keydown.sg", { + 'self': this + }, this.listenForActionKeys); + return jQuerySG("html").bind("keyup.sg", { + 'self': this + }, this.clearActionKeys); + }; + + SelectorGadget.prototype.listenForActionKeys = function(e) { + var gadget; + gadget = e.data.self; + if (gadget.unbound) { + return true; + } + if (e.keyCode === 16 || e.keyCode === 68) { + gadget.special_mode = 'd'; + return gadget.removeBorders(); + } + }; + + SelectorGadget.prototype.clearActionKeys = function(e) { + var gadget; + gadget = e.data.self; + if (gadget.unbound) { + return true; + } + gadget.removeBorders(); + return gadget.special_mode = null; + }; + + SelectorGadget.prototype.blockClicksOn = function(elem) { + var block, p; + elem = jQuerySG(elem); + p = elem.offset(); + block = jQuerySG('
').css('position', 'absolute').css('z-index', '9999999').css('width', this.px(elem.outerWidth())).css('height', this.px(elem.outerHeight())).css('top', this.px(p.top)).css('left', this.px(p.left)).css('background-color', ''); + document.body.appendChild(block.get(0)); + setTimeout((function() { + return block.remove(); + }), 400); + return false; + }; + + SelectorGadget.prototype.setMode = function(mode) { + if (mode === 'browse') { + this.removeEventHandlers(); + } else if (mode === 'interactive') { + this.setupEventHandlers(); + } + return this.clearSelected(); + }; + + SelectorGadget.prototype.suggestPredicted = function(prediction) { + var count; + if (prediction && prediction !== '') { + count = 0; + jQuerySG(prediction).each(function() { + count += 1; + if (!jQuerySG(this).hasClass('selectorgadget_selected') && !jQuerySG(this).hasClass('selectorgadget_ignore') && !jQuerySG(this).hasClass('selectorgadget_rejected')) { + return jQuerySG(this).addClass('selectorgadget_suggested'); + } + }); + if (this.clear_button) { + if (count > 0) { + return this.clear_button.attr('value', 'Clear (' + count + ')'); + } else { + return this.clear_button.attr('value', 'Clear'); + } + } + } + }; + + SelectorGadget.prototype.setPath = function(prediction) { + if (prediction && prediction.length > 0) { + return this.path_output_field.value = prediction; + } else { + return this.path_output_field.value = 'No valid path found.'; + } + }; + + SelectorGadget.prototype.refreshFromPath = function(e) { + var path, self; + self = (e && e.data && e.data.self) || this; + path = self.path_output_field.value; + self.clearSelected(); + self.suggestPredicted(path); + return self.setPath(path); + }; + + SelectorGadget.prototype.showXPath = function(e) { + var path, self; + self = (e && e.data && e.data.self) || this; + path = self.path_output_field.value; + if (path === 'No valid path found.') { + return; + } + return prompt("The CSS selector '" + path + "' as an XPath is shown below. Please report any bugs that you find with this converter.", self.prediction_helper.cssToXPath(path)); + }; + + SelectorGadget.prototype.clearSelected = function(e) { + var self; + self = (e && e.data && e.data.self) || this; + self.selected = []; + self.rejected = []; + jQuerySG('.selectorgadget_selected').removeClass('selectorgadget_selected'); + jQuerySG('.selectorgadget_rejected').removeClass('selectorgadget_rejected'); + self.removeBorders(); + return self.clearSuggested(); + }; + + SelectorGadget.prototype.clearEverything = function(e) { + var self; + self = (e && e.data && e.data.self) || this; + self.clearSelected(); + return self.resetOutputs(); + }; + + SelectorGadget.prototype.resetOutputs = function() { + return this.setPath(); + }; + + SelectorGadget.prototype.clearSuggested = function() { + jQuerySG('.selectorgadget_suggested').removeClass('selectorgadget_suggested'); + if (this.clear_button) { + return this.clear_button.attr('value', 'Clear'); + } + }; + + SelectorGadget.prototype.showHelp = function() { + return alert("Click on a page element that you would like your selector to match (it will turn green). SelectorGadget will then generate a minimal CSS selector for that element, and will highlight (yellow) everything that is matched by the selector. Now click on a highlighted element to reject it (red), or click on an unhighlighted element to add it (green). Through this process of selection and rejection, SelectorGadget helps you to come up with the perfect CSS selector for your needs.\n\nHolding 'shift' while moving the mouse will let you select elements inside of other selected elements."); + }; + + SelectorGadget.prototype.useRemoteInterface = function() { + return window.sg_options && window.sg_options.remote_interface; + }; + + SelectorGadget.prototype.updateRemoteInterface = function(data_obj) { + return this.addScript(this.composeRemoteUrl(window.sg_options.remote_interface, data_obj)); + }; + + SelectorGadget.prototype.composeRemoteUrl = function(url, data_obj) { + var key, params; + params = (url.split("?")[1] && url.split("?")[1].split("&")) || []; + params.push("t=" + (new Date()).getTime()); + params.push("url=" + encodeURIComponent(window.location.href)); + if (data_obj) { + for (key in data_obj) { + params.push(encodeURIComponent(key) + '=' + encodeURIComponent(data_obj[key])); + } + } + if (this.remote_data) { + for (key in this.remote_data) { + params.push(encodeURIComponent("data[" + key + "]") + '=' + encodeURIComponent(this.remote_data[key])); + } + } + return url.split("?")[0] + "?" + params.join("&"); + }; + + SelectorGadget.prototype.addScript = function(src) { + var head, s; + s = document.createElement('script'); + s.setAttribute('type', 'text/javascript'); + s.setAttribute('src', src); + head = document.getElementsByTagName('head')[0]; + if (head) { + return head.appendChild(s); + } else { + return document.body.appendChild(s); + } + }; + + SelectorGadget.prototype.makeInterface = function() { + this.sg_div = jQuerySG('
').attr('id', 'selectorgadget_main').addClass('selectorgadget_bottom').addClass('selectorgadget_ignore'); + if (this.useRemoteInterface()) { + this.path_output_field = { + value: null + }; + this.remote_data = {}; + this.updateRemoteInterface(); + } else { + this.makeStandardInterface(); + } + return jQuerySG('body').append(this.sg_div); + }; + + SelectorGadget.prototype.makeStandardInterface = function() { + var path, self; + self = this; + path = jQuerySG('').attr('id', 'selectorgadget_path_field').addClass('selectorgadget_ignore').addClass('selectorgadget_input_field').keydown(function(e) { + if (e.keyCode === 13) { + return self.refreshFromPath(e); + } + }).focus(function() { + return jQuerySG(this).select(); + }); + this.sg_div.append(path); + this.clear_button = jQuerySG('').bind("click", { + 'self': this + }, this.clearEverything).addClass('selectorgadget_ignore').addClass('selectorgadget_input_field'); + this.sg_div.append(this.clear_button); + this.sg_div.append(jQuerySG('').click(function() { + if (self.sg_div.hasClass('selectorgadget_top')) { + return self.sg_div.removeClass('selectorgadget_top').addClass('selectorgadget_bottom'); + } else { + return self.sg_div.removeClass('selectorgadget_bottom').addClass('selectorgadget_top'); + } + }).addClass('selectorgadget_ignore').addClass('selectorgadget_input_field')); + this.sg_div.append(jQuerySG('').bind("click", { + 'self': this + }, this.showXPath).addClass('selectorgadget_ignore').addClass('selectorgadget_input_field')); + this.sg_div.append(jQuerySG('').bind("click", { + 'self': this + }, this.showHelp).addClass('selectorgadget_ignore').addClass('selectorgadget_input_field')); + this.sg_div.append(jQuerySG('').bind("click", { + 'self': this + }, this.unbindAndRemoveInterface).addClass('selectorgadget_ignore').addClass('selectorgadget_input_field')); + return this.path_output_field = path.get(0); + }; + + SelectorGadget.prototype.removeInterface = function(e) { + this.sg_div.remove(); + return this.sg_div = null; + }; + + SelectorGadget.prototype.unbind = function(e) { + var self; + self = (e && e.data && e.data.self) || this; + self.unbound = true; + self.removeBorderFromDom(); + return self.clearSelected(); + }; + + SelectorGadget.prototype.unbindAndRemoveInterface = function(e) { + var self; + self = (e && e.data && e.data.self) || this; + self.unbind(); + return self.removeInterface(); + }; + + SelectorGadget.prototype.setOutputMode = function(e, output_mode) { + var self; + self = (e && e.data && e.data.self) || this; + return self.output_mode = (e && e.data && e.data.mode) || output_mode; + }; + + SelectorGadget.prototype.rebind = function() { + this.unbound = false; + this.clearEverything(); + return this.setupBorders(); + }; + + SelectorGadget.prototype.rebindAndMakeInterface = function() { + this.makeInterface(); + return this.rebind(); + }; + + SelectorGadget.prototype.randBetween = function(a, b) { + return Math.floor(Math.random() * b) + a; + }; + + SelectorGadget.toggle = function(options) { + if (!window.selector_gadget) { + window.selector_gadget = new SelectorGadget(); + window.selector_gadget.makeInterface(); + window.selector_gadget.clearEverything(); + window.selector_gadget.setMode('interactive'); + if ((options != null ? options.analytics : void 0) !== false) { + window.selector_gadget.analytics(); + } + } else if (window.selector_gadget.unbound) { + window.selector_gadget.rebindAndMakeInterface(); + } else { + window.selector_gadget.unbindAndRemoveInterface(); + } + return jQuerySG('.selector_gadget_loading').remove(); + }; + + SelectorGadget.prototype.analytics = function() { + var cookie, random, referer, today, urchinUrl, uservar, utmac, utmhn, utmn, utmp; + utmac = 'UA-148948-9'; + utmhn = encodeURIComponent('www.selectorgadget.com'); + utmn = this.randBetween(1000000000, 9999999999); + cookie = this.randBetween(10000000, 99999999); + random = this.randBetween(1000000000, 2147483647); + today = Math.round(new Date().getTime() / 1000.0); + referer = encodeURIComponent(window.location.href); + uservar = '-'; + utmp = 'sg'; + urchinUrl = 'http://www.google-analytics.com/__utm.gif?utmwv=1&utmn=' + utmn + '&utmsr=-&utmsc=-&utmul=-&utmje=0&utmfl=-&utmdt=-&utmhn=' + utmhn + '&utmr=' + referer + '&utmp=' + utmp + '&utmac=' + utmac + '&utmcc=__utma%3D' + cookie + '.' + random + '.' + today + '.' + today + '.' + today + '.2%3B%2B__utmb%3D' + cookie + '%3B%2B__utmc%3D' + cookie + '%3B%2B__utmz%3D' + cookie + '.' + today + '.2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D' + cookie + '.' + uservar + '%3B'; + return document.body.appendChild(jQuerySG('').attr('src', urchinUrl).get(0)); + }; + + return SelectorGadget; + + })(); + +}).call(this); diff --git a/spec/compiled/dom-spec.js b/spec/compiled/dom-spec.js index c0ac23a..8acc252 100644 --- a/spec/compiled/dom-spec.js +++ b/spec/compiled/dom-spec.js @@ -1,5 +1,5 @@ (function() { - var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; describe("DomPredictionHelper", function() { var dom, fixtures; @@ -234,34 +234,34 @@ }); return describe("cssToXPath", function() { beforeEach(function() { - var fixture_contents, fixture_name, _results; - _results = []; + var fixture_contents, fixture_name, results; + results = []; for (fixture_name in fixtures) { fixture_contents = fixtures[fixture_name]; - _results.push(jQuerySG("#jasmine-content").append(fixture_contents)); + results.push(jQuerySG("#jasmine-content").append(fixture_contents)); } - return _results; + return results; }); return it("converts css to xpath", function() { - var css, cssAndXPathMatch, expressions, _i, _len, _results; + var css, cssAndXPathMatch, expressions, i, len, results; cssAndXPathMatch = function(css, xpath) { var css_matches, elem, elems; css_matches = jQuerySG(css); elems = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null); while (elem = elems.iterateNext()) { - if (__indexOf.call(css_matches, elem) < 0) { + if (indexOf.call(css_matches, elem) < 0) { return false; } } return true; }; expressions = ['a', '#leaf1', 'body #leaf1', 'span.sibling.something.else', 'a , b , #leaf1', 'span.sibling', '.else.something', ':nth-child(2) i#leaf1', 'span.something.else:nth-child(2) i#leaf1']; - _results = []; - for (_i = 0, _len = expressions.length; _i < _len; _i++) { - css = expressions[_i]; - _results.push(expect(cssAndXPathMatch(css, dom.cssToXPath(css))).toBeTruthy()); + results = []; + for (i = 0, len = expressions.length; i < len; i++) { + css = expressions[i]; + results.push(expect(cssAndXPathMatch(css, dom.cssToXPath(css))).toBeTruthy()); } - return _results; + return results; }); }); }); diff --git a/spec/compiled/dom.js b/spec/compiled/dom.js new file mode 100644 index 0000000..18394db --- /dev/null +++ b/spec/compiled/dom.js @@ -0,0 +1,553 @@ + +/* + The MIT License + + Copyright (c) 2012 Andrew Cantino + Copyright (c) 2009 Andrew Cantino & Kyle Maxwell + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +(function() { + var DomPredictionHelper; + + window.DomPredictionHelper = DomPredictionHelper = (function() { + function DomPredictionHelper() {} + + DomPredictionHelper.prototype.recursiveNodes = function(e) { + var n; + if (e.nodeName && e.parentNode && e !== document.body) { + n = this.recursiveNodes(e.parentNode); + } else { + n = new Array(); + } + n.push(e); + return n; + }; + + DomPredictionHelper.prototype.escapeCssNames = function(name) { + var e; + if (name) { + try { + return name.replace(/\bselectorgadget_\w+\b/g, '').replace(/\\/g, '\\\\').replace(/[\#\;\&\,\.\+\*\~\'\:\"\!\^\$\[\]\(\)\=\>\|\/]/g, function(e) { + return '\\' + e; + }).replace(/\s+/, ''); + } catch (error) { + e = error; + if (window.console) { + console.log('---'); + console.log("exception in escapeCssNames"); + console.log(name); + console.log('---'); + } + return ''; + } + } else { + return ''; + } + }; + + DomPredictionHelper.prototype.childElemNumber = function(elem) { + var count; + count = 0; + while (elem.previousSibling && (elem = elem.previousSibling)) { + if (elem.nodeType === 1) { + count++; + } + } + return count; + }; + + DomPredictionHelper.prototype.siblingsWithoutTextNodes = function(e) { + var filtered_nodes, k, len, node, nodes; + nodes = e.parentNode.childNodes; + filtered_nodes = []; + for (k = 0, len = nodes.length; k < len; k++) { + node = nodes[k]; + if (node.nodeName.substring(0, 1) === "#") { + continue; + } + if (node === e) { + break; + } + filtered_nodes.push(node); + } + return filtered_nodes; + }; + + DomPredictionHelper.prototype.pathOf = function(elem) { + var e, j, k, len, path, ref, siblings; + path = ""; + ref = this.recursiveNodes(elem); + for (k = 0, len = ref.length; k < len; k++) { + e = ref[k]; + if (e) { + siblings = this.siblingsWithoutTextNodes(e); + if (e.nodeName.toLowerCase() !== "body") { + j = siblings.length - 2 < 0 ? 0 : siblings.length - 2; + while (j < siblings.length) { + if (siblings[j] === e) { + break; + } + if (!siblings[j].nodeName.match(/^(script|#.*?)$/i)) { + path += this.cssDescriptor(siblings[j]) + (j + 1 === siblings.length ? "+ " : "~ "); + } + j++; + } + } + path += this.cssDescriptor(e) + " > "; + } + } + return this.cleanCss(path); + }; + + DomPredictionHelper.prototype.cssDescriptor = function(node) { + var cssName, escaped, k, len, path, ref; + path = node.nodeName.toLowerCase(); + escaped = node.id && this.escapeCssNames(new String(node.id)); + if (escaped && escaped.length > 0) { + path += '#' + escaped; + } + if (node.className) { + ref = node.className.split(" "); + for (k = 0, len = ref.length; k < len; k++) { + cssName = ref[k]; + escaped = this.escapeCssNames(cssName); + if (cssName && escaped.length > 0) { + path += '.' + escaped; + } + } + } + if (node.nodeName.toLowerCase() !== "body") { + path += ':nth-child(' + (this.childElemNumber(node) + 1) + ')'; + } + return path; + }; + + DomPredictionHelper.prototype.cssDiff = function(array) { + var collective_common, cssElem, diff, dmp, e, encoded_css_array, existing_tokens, k, l, len, len1, part; + try { + dmp = new diff_match_patch(); + } catch (error) { + e = error; + throw "Please include the diff_match_patch library."; + } + if (typeof array === 'undefined' || array.length === 0) { + return ''; + } + existing_tokens = {}; + encoded_css_array = this.encodeCssForDiff(array, existing_tokens); + collective_common = encoded_css_array.pop(); + for (k = 0, len = encoded_css_array.length; k < len; k++) { + cssElem = encoded_css_array[k]; + diff = dmp.diff_main(collective_common, cssElem); + collective_common = ''; + for (l = 0, len1 = diff.length; l < len1; l++) { + part = diff[l]; + if (part[0] === 0) { + collective_common += part[1]; + } + } + } + return this.decodeCss(collective_common, existing_tokens); + }; + + DomPredictionHelper.prototype.tokenizeCss = function(css_string) { + var char, k, len, ref, skip, tokens, word; + skip = false; + word = ''; + tokens = []; + ref = this.cleanCss(css_string); + for (k = 0, len = ref.length; k < len; k++) { + char = ref[k]; + if (skip) { + skip = false; + } else if (char === '\\') { + skip = true; + } else if (char === '.' || char === ' ' || char === '#' || char === '>' || char === ':' || char === ',' || char === '+' || char === '~') { + if (word.length > 0) { + tokens.push(word); + } + word = ''; + } + word += char; + if (char === ' ' || char === ',') { + tokens.push(word); + word = ''; + } + } + if (word.length > 0) { + tokens.push(word); + } + return tokens; + }; + + DomPredictionHelper.prototype.tokenizeCssForDiff = function(css_string) { + var block, combined_tokens, k, len, ref, token; + combined_tokens = []; + block = []; + ref = this.tokenizeCss(css_string); + for (k = 0, len = ref.length; k < len; k++) { + token = ref[k]; + block.push(token); + if (token === ' ' && block.length > 0) { + combined_tokens = combined_tokens.concat(block); + block = []; + } else if (token === '+' || token === '~') { + block = [block.join('')]; + } + } + if (block.length > 0) { + return combined_tokens.concat(block); + } else { + return combined_tokens; + } + }; + + DomPredictionHelper.prototype.decodeCss = function(string, existing_tokens) { + var character, inverted, k, len, out, ref; + inverted = this.invertObject(existing_tokens); + out = ''; + ref = string.split(''); + for (k = 0, len = ref.length; k < len; k++) { + character = ref[k]; + out += inverted[character]; + } + return this.cleanCss(out); + }; + + DomPredictionHelper.prototype.encodeCssForDiff = function(strings, existing_tokens) { + var codepoint, k, l, len, len1, out, ref, string, strings_out, token; + codepoint = 50; + strings_out = []; + for (k = 0, len = strings.length; k < len; k++) { + string = strings[k]; + out = new String(); + ref = this.tokenizeCssForDiff(string); + for (l = 0, len1 = ref.length; l < len1; l++) { + token = ref[l]; + if (!existing_tokens[token]) { + existing_tokens[token] = String.fromCharCode(codepoint++); + } + out += existing_tokens[token]; + } + strings_out.push(out); + } + return strings_out; + }; + + DomPredictionHelper.prototype.tokenPriorities = function(tokens) { + var epsilon, first, i, k, len, priorities, second, token; + epsilon = 0.001; + priorities = new Array(); + i = 0; + for (k = 0, len = tokens.length; k < len; k++) { + token = tokens[k]; + first = token.substring(0, 1); + second = token.substring(1, 2); + if (first === ':' && second === 'n') { + priorities[i] = 0; + } else if (first === '>') { + priorities[i] = 2; + } else if (first === '+' || first === '~') { + priorities[i] = 3; + } else if (first !== ':' && first !== '.' && first !== '#' && first !== ' ' && first !== '>' && first !== '+' && first !== '~') { + priorities[i] = 4; + } else if (first === '.') { + priorities[i] = 5; + } else if (first = '#') { + priorities[i] = 6; + if (token.match(/\d{3,}/)) { + priorities[i] = 2.5; + } + } else { + priorities[i] = 0; + } + priorities[i] += i * epsilon; + i++; + } + return priorities; + }; + + DomPredictionHelper.prototype.orderFromPriorities = function(priorities) { + var i, k, l, ordering, ref, ref1, tmp; + tmp = new Array(); + ordering = new Array(); + for (i = k = 0, ref = priorities.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { + tmp[i] = { + value: priorities[i], + original: i + }; + } + tmp.sort(function(a, b) { + return a.value - b.value; + }); + for (i = l = 0, ref1 = priorities.length; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) { + ordering[i] = tmp[i].original; + } + return ordering; + }; + + DomPredictionHelper.prototype.simplifyCss = function(css, selected, rejected) { + var best_so_far, first, got_shorter, i, k, look_back_index, ordering, part, parts, priorities, ref, second, selector; + parts = this.tokenizeCss(css); + priorities = this.tokenPriorities(parts); + ordering = this.orderFromPriorities(priorities); + selector = this.cleanCss(css); + look_back_index = -1; + best_so_far = ""; + if (this.selectorGets('all', selected, selector) && this.selectorGets('none', rejected, selector)) { + best_so_far = selector; + } + got_shorter = true; + while (got_shorter) { + got_shorter = false; + for (i = k = 0, ref = parts.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { + part = ordering[i]; + if (parts[part].length === 0) { + continue; + } + first = parts[part].substring(0, 1); + second = parts[part].substring(1, 2); + if (first === ' ') { + continue; + } + if (this.wouldLeaveFreeFloatingNthChild(parts, part)) { + continue; + } + this._removeElements(part, parts, first, (function(_this) { + return function(selector) { + if (_this.selectorGets('all', selected, selector) && _this.selectorGets('none', rejected, selector) && (selector.length < best_so_far.length || best_so_far.length === 0)) { + best_so_far = selector; + got_shorter = true; + return true; + } else { + return false; + } + }; + })(this)); + } + } + return this.cleanCss(best_so_far); + }; + + DomPredictionHelper.prototype._removeElements = function(part, parts, firstChar, callback) { + var j, k, l, look_back_index, ref, ref1, ref2, ref3, selector, tmp; + if (firstChar === '+' || firstChar === '~') { + look_back_index = this.positionOfSpaceBeforeIndexOrLineStart(part, parts); + } else { + look_back_index = part; + } + tmp = parts.slice(look_back_index, part + 1); + for (j = k = ref = look_back_index, ref1 = part; ref <= ref1 ? k <= ref1 : k >= ref1; j = ref <= ref1 ? ++k : --k) { + parts[j] = ''; + } + selector = this.cleanCss(parts.join('')); + if (selector === '' || !callback(selector)) { + for (j = l = ref2 = look_back_index, ref3 = part; ref2 <= ref3 ? l <= ref3 : l >= ref3; j = ref2 <= ref3 ? ++l : --l) { + parts[j] = tmp[j - look_back_index]; + } + } + return parts; + }; + + DomPredictionHelper.prototype.positionOfSpaceBeforeIndexOrLineStart = function(part, parts) { + var i; + i = part; + while (i >= 0 && parts[i] !== ' ') { + i--; + } + if (i < 0) { + i = 0; + } + return i; + }; + + DomPredictionHelper.prototype.wouldLeaveFreeFloatingNthChild = function(parts, part) { + var i, nth_child_is_on_right, space_is_on_left; + space_is_on_left = nth_child_is_on_right = false; + i = part + 1; + while (i < parts.length && parts[i].length === 0) { + i++; + } + if (i < parts.length && parts[i].substring(0, 2) === ':n') { + nth_child_is_on_right = true; + } + i = part - 1; + while (i > -1 && parts[i].length === 0) { + i--; + } + if (i < 0 || parts[i] === ' ') { + space_is_on_left = true; + } + return space_is_on_left && nth_child_is_on_right; + }; + + DomPredictionHelper.prototype.cleanCss = function(css) { + var cleaned_css, last_cleaned_css; + cleaned_css = css; + last_cleaned_css = null; + while (last_cleaned_css !== cleaned_css) { + last_cleaned_css = cleaned_css; + cleaned_css = cleaned_css.replace(/(^|\s+)(\+|\~)/, '').replace(/(\+|\~)\s*$/, '').replace(/>/g, ' > ').replace(/\s*(>\s*)+/g, ' > ').replace(/,/g, ' , ').replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '').replace(/\s*,$/g, '').replace(/^\s*,\s*/g, '').replace(/\s*>$/g, '').replace(/^>\s*/g, '').replace(/[\+\~\>]\s*,/g, ',').replace(/[\+\~]\s*>/g, '>').replace(/\s*(,\s*)+/g, ' , '); + } + return cleaned_css; + }; + + DomPredictionHelper.prototype.getPathsFor = function(nodeset) { + var k, len, node, out; + out = []; + for (k = 0, len = nodeset.length; k < len; k++) { + node = nodeset[k]; + if (node && node.nodeName) { + out.push(this.pathOf(node)); + } + } + return out; + }; + + DomPredictionHelper.prototype.predictCss = function(s, r) { + var css, k, len, selected, selected_paths, simplest, union; + if (s.length === 0) { + return ''; + } + selected_paths = this.getPathsFor(s); + css = this.cssDiff(selected_paths); + simplest = this.simplifyCss(css, s, r); + if (simplest.length > 0) { + return simplest; + } + union = ''; + for (k = 0, len = s.length; k < len; k++) { + selected = s[k]; + union = this.pathOf(selected) + ", " + union; + } + union = this.cleanCss(union); + return this.simplifyCss(union, s, r); + }; + + DomPredictionHelper.prototype.selectorGets = function(type, list, the_selector) { + var e; + if (list.length === 0 && type === 'all') { + return false; + } + if (list.length === 0 && type === 'none') { + return true; + } + try { + if (type === 'all') { + return list.not(the_selector).length === 0; + } else { + return !(list.is(the_selector)); + } + } catch (error) { + e = error; + if (window.console) { + console.log("Error on selector: " + the_selector); + } + throw e; + } + }; + + DomPredictionHelper.prototype.invertObject = function(object) { + var key, new_object, value; + new_object = {}; + for (key in object) { + value = object[key]; + new_object[value] = key; + } + return new_object; + }; + + DomPredictionHelper.prototype.cssToXPath = function(css_string) { + var css_block, k, len, out, token, tokens; + tokens = this.tokenizeCss(css_string); + if (tokens[0] && tokens[0] === ' ') { + tokens.splice(0, 1); + } + if (tokens[tokens.length - 1] && tokens[tokens.length - 1] === ' ') { + tokens.splice(tokens.length - 1, 1); + } + css_block = []; + out = ""; + for (k = 0, len = tokens.length; k < len; k++) { + token = tokens[k]; + if (token === ' ') { + out += this.cssToXPathBlockHelper(css_block); + css_block = []; + } else { + css_block.push(token); + } + } + return out + this.cssToXPathBlockHelper(css_block); + }; + + DomPredictionHelper.prototype.cssToXPathBlockHelper = function(css_block) { + var current, expressions, first, i, k, l, len, out, re, ref, rest; + if (css_block.length === 0) { + return '//'; + } + out = '//'; + first = css_block[0].substring(0, 1); + if (first === ',') { + return " | "; + } + if (first === ':' || first === '#' || first === '.') { + out += '*'; + } + expressions = []; + re = null; + for (k = 0, len = css_block.length; k < len; k++) { + current = css_block[k]; + first = current.substring(0, 1); + rest = current.substring(1); + if (first === ':') { + if (re = rest.match(/^nth-child\((\d+)\)$/)) { + expressions.push('(((count(preceding-sibling::*) + 1) = ' + re[1] + ') and parent::*)'); + } + } else if (first === '.') { + expressions.push('contains(concat( " ", @class, " " ), concat( " ", "' + rest + '", " " ))'); + } else if (first === '#') { + expressions.push('(@id = "' + rest + '")'); + } else if (first === ',') { + + } else { + out += current; + } + } + if (expressions.length > 0) { + out += '['; + } + for (i = l = 0, ref = expressions.length; 0 <= ref ? l < ref : l > ref; i = 0 <= ref ? ++l : --l) { + out += expressions[i]; + if (i < expressions.length - 1) { + out += ' and '; + } + } + if (expressions.length > 0) { + out += ']'; + } + return out; + }; + + return DomPredictionHelper; + + })(); + +}).call(this); diff --git a/spec/compiled/jquery-include.js b/spec/compiled/jquery-include.js new file mode 100644 index 0000000..e5ba392 --- /dev/null +++ b/spec/compiled/jquery-include.js @@ -0,0 +1,4 @@ +(function() { + window.jQuerySG = jQuery.noConflict(true); + +}).call(this); diff --git a/spec/compiled/spec-helper.js b/spec/compiled/spec-helper.js index b4cd60b..2ca5f0c 100644 --- a/spec/compiled/spec-helper.js +++ b/spec/compiled/spec-helper.js @@ -1,5 +1,4 @@ (function() { - beforeEach(function() { jQuerySG.fx.off = true; jQuerySG('#jasmine-content').empty(); @@ -10,14 +9,14 @@ }); afterEach(function() { - var events, prop, _results; + var events, prop, results; jasmine.Clock.reset(); events = jQuerySG.data(document, "events"); - _results = []; + results = []; for (prop in events) { - _results.push(delete events[prop]); + results.push(delete events[prop]); } - return _results; + return results; }); }).call(this); diff --git a/spec/compiled/wizard-spec.js b/spec/compiled/wizard-spec.js index f07a12f..a406c14 100644 --- a/spec/compiled/wizard-spec.js +++ b/spec/compiled/wizard-spec.js @@ -1,8 +1,7 @@ (function() { - describe("SelectorGadget wizard features", function() { - var otherCard, selectorCard, sg, struct, _ref; - _ref = [null, null, null, null], sg = _ref[0], selectorCard = _ref[1], otherCard = _ref[2], struct = _ref[3]; + var otherCard, ref, selectorCard, sg, struct; + ref = [null, null, null, null], sg = ref[0], selectorCard = ref[1], otherCard = ref[2], struct = ref[3]; beforeEach(function() { sg = new SelectorGadget(); selectorCard = {