Merge "Allow passing nils to mw.html"

This commit is contained in:
jenkins-bot 2014-06-19 16:57:02 +00:00 committed by Gerrit Code Review
commit 8d7d5f35ed
2 changed files with 74 additions and 26 deletions

View file

@ -52,13 +52,13 @@ metatable.__tostring = function( t )
return table.concat( ret ) return table.concat( ret )
end end
-- Get an attribute table (name, value) -- Get an attribute table (name, value) and its index
-- --
-- @param name -- @param name
local function getAttr( t, name ) local function getAttr( t, name )
for i, attr in ipairs( t.attributes ) do for i, attr in ipairs( t.attributes ) do
if attr.name == name then if attr.name == name then
return attr return attr, i
end end
end end
end end
@ -196,7 +196,7 @@ end
-- Set an HTML attribute on the node. -- Set an HTML attribute on the node.
-- --
-- @param name Attribute to set, alternative table of name-value pairs -- @param name Attribute to set, alternative table of name-value pairs
-- @param val Value of the attribute -- @param val Value of the attribute. Nil causes the attribute to be unset
methodtable.attr = function( t, name, val ) methodtable.attr = function( t, name, val )
if type( name ) == 'table' then if type( name ) == 'table' then
if val ~= nil then if val ~= nil then
@ -219,7 +219,7 @@ methodtable.attr = function( t, name, val )
if type( name ) ~= 'string' and type( name ) ~= 'number' then if type( name ) ~= 'string' and type( name ) ~= 'number' then
error( 'Invalid name given: The name must be either a string or a number' ) error( 'Invalid name given: The name must be either a string or a number' )
end end
if type( val ) ~= 'string' and type( val ) ~= 'number' then if val ~= nil and type( val ) ~= 'string' and type( val ) ~= 'number' then
error( 'Invalid value given: The value must be either a string or a number' ) error( 'Invalid value given: The value must be either a string or a number' )
end end
@ -234,10 +234,14 @@ methodtable.attr = function( t, name, val )
error( "Invalid attribute name: " .. name ) error( "Invalid attribute name: " .. name )
end end
local attr = getAttr( t, name ) local attr, i = getAttr( t, name )
if attr then if attr then
if val ~= nil then
attr.val = val attr.val = val
else else
table.remove( t.attributes, i )
end
elseif val ~= nil then
table.insert( t.attributes, { name = name, val = val } ) table.insert( t.attributes, { name = name, val = val } )
end end
@ -249,6 +253,10 @@ end
-- --
-- @param class -- @param class
methodtable.addClass = function( t, class ) methodtable.addClass = function( t, class )
if class == nil then
return t
end
if type( class ) ~= 'string' and type( class ) ~= 'number' then if type( class ) ~= 'string' and type( class ) ~= 'number' then
error( 'Invalid class given: The name must be either a string or a number' ) error( 'Invalid class given: The name must be either a string or a number' )
end end
@ -266,7 +274,7 @@ end
-- Set a CSS property to be added to the node's style attribute. -- Set a CSS property to be added to the node's style attribute.
-- --
-- @param name CSS attribute to set, alternative table of name-value pairs -- @param name CSS attribute to set, alternative table of name-value pairs
-- @param val -- @param val The value to set. Nil causes it to be unset
methodtable.css = function( t, name, val ) methodtable.css = function( t, name, val )
if type( name ) == 'table' then if type( name ) == 'table' then
if val ~= nil then if val ~= nil then
@ -289,18 +297,24 @@ methodtable.css = function( t, name, val )
if type( name ) ~= 'string' and type( name ) ~= 'number' then if type( name ) ~= 'string' and type( name ) ~= 'number' then
error( 'Invalid CSS given: The name must be either a string or a number' ) error( 'Invalid CSS given: The name must be either a string or a number' )
end end
if type( val ) ~= 'string' and type( val ) ~= 'number' then if val ~= nil and type( val ) ~= 'string' and type( val ) ~= 'number' then
error( 'Invalid CSS given: The value must be either a string or a number' ) error( 'Invalid CSS given: The value must be either a string or a number' )
end end
for i, prop in ipairs( t.styles ) do for i, prop in ipairs( t.styles ) do
if prop.name == name then if prop.name == name then
if val ~= nil then
prop.val = val prop.val = val
else
table.remove( t.styles, i )
end
return t return t
end end
end end
if val ~= nil then
table.insert( t.styles, { name = name, val = val } ) table.insert( t.styles, { name = name, val = val } )
end
return t return t
end end
@ -310,11 +324,11 @@ end
-- --
-- @param css -- @param css
methodtable.cssText = function( t, css ) methodtable.cssText = function( t, css )
if css ~= nil then
if type( css ) ~= 'string' and type( css ) ~= 'number' then if type( css ) ~= 'string' and type( css ) ~= 'number' then
error( 'Invalid CSS given: Must be either a string or a number' ) error( 'Invalid CSS given: Must be either a string or a number' )
end end
if css then
table.insert( t.styles, css ) table.insert( t.styles, css )
end end
return t return t
@ -341,6 +355,7 @@ end
-- @param tagName -- @param tagName
-- @param args -- @param args
function HtmlBuilder.create( tagName, args ) function HtmlBuilder.create( tagName, args )
if tagName ~= nil then
if type( tagName ) ~= 'string' then if type( tagName ) ~= 'string' then
error( "Tag name must be a string" ) error( "Tag name must be a string" )
end end
@ -348,6 +363,7 @@ function HtmlBuilder.create( tagName, args )
if tagName ~= '' and not isValidTag( tagName ) then if tagName ~= '' and not isValidTag( tagName ) then
error( "Invalid tag name: " .. tagName ) error( "Invalid tag name: " .. tagName )
end end
end
args = args or {} args = args or {}
local builder = {} local builder = {}

View file

@ -55,6 +55,10 @@ local function testAttributeOverride()
return getEmptyTestDiv():attr( 'good', 'MediaWiki' ):attr( 'good', 'Wikibase' ) return getEmptyTestDiv():attr( 'good', 'MediaWiki' ):attr( 'good', 'Wikibase' )
end end
local function testAttributeRemoval()
return getEmptyTestDiv():attr( 'a', 'b' ):attr( 'a', nil )
end
local function testGetAttribute() local function testGetAttribute()
return getEmptyTestDiv():attr( 'town', 'Berlin' ):getAttr( 'town' ) return getEmptyTestDiv():attr( 'town', 'Berlin' ):getAttr( 'town' )
end end
@ -75,8 +79,12 @@ local function testWikitextAppendToSelfClosing()
return mw.html.create( 'hr' ):wikitext( 'foo' ) return mw.html.create( 'hr' ):wikitext( 'foo' )
end end
local function testEmptyCreate() local function testCreateWithValue( val )
return mw.html.create( '' ):wikitext( 'foo' ):tag( 'div' ):attr( 'a', 'b' ):allDone() return mw.html.create( val ):wikitext( 'foo' ):tag( 'div' ):attr( 'a', 'b' ):allDone()
end
local function testCssRemoval()
return getEmptyTestDiv():css( 'color', 'red' ):css( 'color', nil )
end end
local function testComplex() local function testComplex()
@ -116,9 +124,6 @@ local tests = {
args = { {} }, args = { {} },
expect = 'Tag name must be a string' expect = 'Tag name must be a string'
}, },
{ name = 'mw.html.create (invalid tag 3)', func = mw.html.create, type='ToString',
expect = 'Tag name must be a string'
},
{ name = 'mw.html.wikitext', func = testHelper, type='ToString', { name = 'mw.html.wikitext', func = testHelper, type='ToString',
args = { getEmptyTestDiv(), 'wikitext', 'Plain text' }, args = { getEmptyTestDiv(), 'wikitext', 'Plain text' },
expect = { '<div>Plain text</div>' } expect = { '<div>Plain text</div>' }
@ -140,6 +145,10 @@ local tests = {
args = { getEmptyTestDiv(), 'attr', 'foo', 'bar' }, args = { getEmptyTestDiv(), 'attr', 'foo', 'bar' },
expect = { '<div foo="bar"></div>' } expect = { '<div foo="bar"></div>' }
}, },
{ name = 'mw.html.attr (nil noop)', func = testHelper, type='ToString',
args = { getEmptyTestDiv(), 'attr', 'foo', nil },
expect = { '<div></div>' }
},
{ name = 'mw.html.attr (table 1)', func = testHelper, type='ToString', { name = 'mw.html.attr (table 1)', func = testHelper, type='ToString',
args = { getEmptyTestDiv(), 'attr', { foo = 'bar' } }, args = { getEmptyTestDiv(), 'attr', { foo = 'bar' } },
expect = { '<div foo="bar"></div>' } expect = { '<div foo="bar"></div>' }
@ -196,6 +205,10 @@ local tests = {
args = { getEmptyTestDiv(), 'css', 'foo', 'bar' }, args = { getEmptyTestDiv(), 'css', 'foo', 'bar' },
expect = { '<div style="foo:bar;"></div>' } expect = { '<div style="foo:bar;"></div>' }
}, },
{ name = 'mw.html.css (nil noop)', func = testHelper, type='ToString',
args = { getEmptyTestDiv(), 'css', 'foo', nil },
expect = { '<div></div>' }
},
{ name = 'mw.html.css (invalid name 1)', func = testHelper, type='ToString', { name = 'mw.html.css (invalid name 1)', func = testHelper, type='ToString',
args = { getEmptyTestDiv(), 'css', function() end, 'bar' }, args = { getEmptyTestDiv(), 'css', function() end, 'bar' },
expect = 'Invalid CSS given: The name must be either a string or a number' expect = 'Invalid CSS given: The name must be either a string or a number'
@ -244,6 +257,14 @@ local tests = {
args = { getEmptyTestDiv(), 'cssText', 'mu"ha:-ha"ha' }, args = { getEmptyTestDiv(), 'cssText', 'mu"ha:-ha"ha' },
expect = { '<div style="mu&quot;ha:-ha&quot;ha;"></div>' } expect = { '<div style="mu&quot;ha:-ha&quot;ha;"></div>' }
}, },
{ name = 'mw.html.addClass (nil)', func = testHelper, type='ToString',
args = { getEmptyTestDiv(), 'addClass' },
expect = { '<div></div>' }
},
{ name = 'mw.html.cssText (nil)', func = testHelper, type='ToString',
args = { getEmptyTestDiv(), 'cssText' },
expect = { '<div></div>' }
},
-- Tests defined above -- Tests defined above
@ -274,15 +295,26 @@ local tests = {
{ name = 'mw.html.attr (overrides)', func = testAttributeOverride, type='ToString', { name = 'mw.html.attr (overrides)', func = testAttributeOverride, type='ToString',
expect = { '<div good="Wikibase"></div>' } expect = { '<div good="Wikibase"></div>' }
}, },
{ name = 'mw.html.attr (removal)', func = testAttributeRemoval, type='ToString',
expect = { '<div></div>' }
},
{ name = 'mw.html.getAttr', func = testGetAttribute, type='ToString', { name = 'mw.html.getAttr', func = testGetAttribute, type='ToString',
expect = { 'Berlin' } expect = { 'Berlin' }
}, },
{ name = 'mw.html.getAttr (escaping)', func = testGetAttributeEscaping, type='ToString', { name = 'mw.html.getAttr (escaping)', func = testGetAttributeEscaping, type='ToString',
expect = { '<ble"&rgh>' } expect = { '<ble"&rgh>' }
}, },
{ name = 'mw.html.create (empty)', func = testEmptyCreate, type='ToString', { name = 'mw.html.create (empty string)', func = testCreateWithValue, type='ToString',
args = {''},
expect = { 'foo<div a="b"></div>' } expect = { 'foo<div a="b"></div>' }
}, },
{ name = 'mw.html.create (nil)', func = testCreateWithValue, type='ToString',
args = {nil},
expect = { 'foo<div a="b"></div>' }
},
{ name = 'mw.html.css (removal)', func = testCssRemoval, type='ToString',
expect = { '<div></div>' }
},
{ name = 'mw.html complex test', func = testComplex, type='ToString', { name = 'mw.html complex test', func = testComplex, type='ToString',
expect = { expect = {
'<div class="firstClass" what="ever"><meh whynot="Русский"><hr a="b" /></meh>' .. '<div class="firstClass" what="ever"><meh whynot="Русский"><hr a="b" /></meh>' ..